Mybatis-Plus的使用

目录

 


 
 
回到顶部

1. 什么是 Mybatis-Plus

  MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
 
回到顶部

2. 为什么要学习 Mybatis-Plus

  我们已经学习过 Mybatis 这个框架,我们只需要在 dao 层定义抽象接口,基于 Mybatis 零实现的特性,就可以实现对数据库的 crud 操作。
  如下两个接口:
  UserMapper 接口
public interface UserMapper {
    int deleteByPrimaryKey(Long id);
    int insert(User user);
    List<User> selectList();
    User selectByPrimaryKey(Long id);
}

 

  OrderMapper 接口
public interface OrderMapper {
 
    int deleteByPrimaryKey(Long id);
    int insert(Order order);
    List<Order> selectList();
    User selectByPrimaryKey(Long id);
}

 

  从上面两个业务接口中,我们发现:它们定义了一组类似的 crud 方法。在业务类型比较多的时候,我们就需要重复的定义这组功能类似的接口方法。如何解决这个问题呢?
  如果使用 Mybatis-plus,甚至都不需要任何的 xml 映射文件或者接口方法注解,只需要让我们定义的抽象接口继承一个公用的 BaseMapper 接口就能完成 dao 层的一些基本的通用方法(如 crud),做到真正的 dao 层零实现。
public interface UserMapper extends BaseMapper<User> {
   //BaseMapper 已经实现了基本的通用方法了。如果有需要非通用的操作,才在这里自定义
}

 

 
回到顶部

3. 入门示例

3.1 说明

  1.Mybatis-Plus 并没有提供单独的 jar 包,而是通过 Maven(或者 gradle)来管理 jar 依赖。所以需要使用 Maven 构建项目。
  2.Mybatis-Plus 是基于 Spring 框架实现的,因此使用 Mybatis-Plus,必须导入 Spring 相关依赖。
 

3.2 准备工作

  先创建好了数据库环境
  建表语句:
  
CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL COMMENT '主键 ID',
  `name` varchar(30) DEFAULT NULL COMMENT '姓名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (`id`)
)

 

 

3.3 配置步骤

3.3.1 第一步:搭建环境

1. 创建一个 Maven 项目
0
2. 配置 pom.xml 文件
导入相关依赖,并且配置项目的编码,JDK 版本等构建信息
<
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gjs</groupId>
  <artifactId>mybatis-plus-01-start</artifactId>
  <version>1.0</version>

<dependencies>
<!-- spring 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.20.RELEASE</version>
</dependency>

  &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
      &lt;version&gt;4.3.20.RELEASE&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-test&lt;/artifactId&gt;
    &lt;version&gt;4.3.20.RELEASE&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
  
  &lt;!-- mybatis-plus --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.baomidou&lt;/groupId&gt;
    &lt;artifactId&gt;mybatis-plus&lt;/artifactId&gt;
    &lt;version&gt;2.3&lt;/version&gt;
&lt;/dependency&gt;

&lt;!-- Mysql 驱动 --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;mysql&lt;/groupId&gt;
    &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
    &lt;version&gt;5.1.47&lt;/version&gt;
&lt;/dependency&gt;

&lt;!-- 连接池 --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.alibaba&lt;/groupId&gt;
    &lt;artifactId&gt;druid&lt;/artifactId&gt;
    &lt;version&gt;1.1.9&lt;/version&gt;
&lt;/dependency&gt;

&lt;!-- junit --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;junit&lt;/groupId&gt;
    &lt;artifactId&gt;junit&lt;/artifactId&gt;
    &lt;version&gt;4.12&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;

</dependencies>

<!-- 只要配置了 build 标签里面的内容,配置后都需要强制更新项目 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- 设置编码 -->
<encoding>utf-8</encoding>
<!-- 设置 JDK 版本 -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 设置安装 install 命令的时候跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>

  &lt;/plugins&gt;

</build>
</project>

 

 

3.3.2 第二步:Mybatis-Plus 整合 Spring

Mybatis-Plus 整合 Spring 和 Mybatis 整合 Spring 差不多,只是会话工厂从 org.mybatis.spring.SqlSessionFactoryBean 换成 com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    <!-- 1. 配置数据源 -->
    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis-plus"></property>
          <property name="username" value="root"></property>
           <property name="password" value="1234"></property>
           <!-- 最大连接数 -->
          <property name="maxActive" value="10"></property>
         <!-- 超时毫秒数 -->
           <property name="maxWait" value="30000"></property>
    </bean>
&lt;!-- 2.配置会话工厂 --&gt;
&lt;bean name="sqlSessionFactory" <span style="color: rgba(0, 0, 255, 1)">class</span>="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"&gt;
    &lt;!-- 指定数据源 --&gt;
    &lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;

&lt;!-- 3.配置映射动态代理对象到spring容器 --&gt;
&lt;bean <span style="color: rgba(0, 0, 255, 1)">class</span>="org.mybatis.spring.mapper.MapperScannerConfigurer"&gt;
    &lt;!-- 指定会话工厂 --&gt;
    &lt;property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/&gt;
    &lt;!-- 指定扫描的映射包 --&gt;
    &lt;property name="basePackage" value="com.gjs.mybatisplus.mapper"/&gt;
&lt;/bean&gt;
&lt;!-- 4.配置事务管理器 --&gt;
&lt;bean name="tx" <span style="color: rgba(0, 0, 255, 1)">class</span>="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
    &lt;property name="dataSource" ref="dataSource"&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;tx:annotation-driven transaction-manager="tx"/&gt;

</beans>

 

 

3.3.3 第三步:编写 POJO

  使用 Mybatis-Plus 不使用 xml 文件,而是基于一组注解来解决实体类和数据库表的映射问题。
注解
作用
@TableName(value="tb_user")
指定对应的表,表名和类名一致时,可以省略 value 属性。
@TableId
指定表的主键。Value 属性指定表的主键字段,和属性名一致时,可以省略。Type 指定主键的增长策略。
@TableField
指定类的属性映射的表字段,名称一致时可以省略该注解。
 
package com.gjs.mybatisplus.pojo;

import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
@TableName(value
="tb_user")
public class User {
/
AUTO->0("数据库 ID 自增")
INPUT->1(用户输入 ID")
ID_WORKER->2("全局唯一 ID")
UUID->3("全局唯一 ID")
NONE-> 4 ("不需要 ID")
/
@TableId(value
="id",type=IdType.AUTO)
private Long id;
//如果属性名与数据库表的字段名相同可以不写
@TableField(value="name")
private String name;
@TableField(value
="age")
private Integer age;
@TableField(value
="email")
private String email;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

 

3.3.4 第四步:编写 Mapper 接口

package com.gjs.mybatisplus.mapper;

import org.springframework.stereotype.Repository;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.gjs.mybatisplus.pojo.User;

@Repository
public interface UserMapper extends BaseMapper<User>{

}

 

3.3.5 编写测试类

package com.gjs.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.gjs.mybatisplus.mapper.UserMapper;
import com.gjs.mybatisplus.pojo.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations
="classpath:spring-data.xml")
public class TestUserMapper {
@Autowired
private UserMapper userMapper;

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 添加
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Test
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> insert() {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        User user</span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> User();
        user.setName(</span>"zhangsan"<span style="color: rgba(0, 0, 0, 1)">);
        user.setAge(</span>20<span style="color: rgba(0, 0, 0, 1)">);
        user.setEmail(</span>"zhangsan@163.com"<span style="color: rgba(0, 0, 0, 1)">);
        Integer insert </span>=<span style="color: rgba(0, 0, 0, 1)"> userMapper.insert(user);
        System.out.println(insert);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
    }
}

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 通过id删除
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Test
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> deleteById() {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        Integer count </span>= userMapper.deleteById(1L<span style="color: rgba(0, 0, 0, 1)">);
        System.out.println(count);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
    }
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 通过条件删除
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Test
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> deleteByCondition() {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置条件</span>
        EntityWrapper&lt;User&gt; wrapper=<span style="color: rgba(0, 0, 255, 1)">new</span> EntityWrapper&lt;&gt;<span style="color: rgba(0, 0, 0, 1)">();
        wrapper.like(</span>"name", "%wang%"<span style="color: rgba(0, 0, 0, 1)">);
        Integer count </span>=<span style="color: rgba(0, 0, 0, 1)"> userMapper.delete(wrapper);
        System.out.println(count);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
    }
}

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 更新非空字段,通过id
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Test
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> update() {
    User user</span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">  User();
    user.setName(</span>"lisi"<span style="color: rgba(0, 0, 0, 1)">);
    user.setEmail(</span>"lisi@163.com"<span style="color: rgba(0, 0, 0, 1)">);
    user.setId(</span>2L<span style="color: rgba(0, 0, 0, 1)">);
    userMapper.updateById(user);
    
}

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 查询所有
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Test
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> findAll() {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查询条件为空时,查询所有</span>
    List&lt;User&gt; users = userMapper.selectList(<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (User user : users) {
        System.out.println(user.getName());
    }
}

}

 

回到顶部

4. 常用配置

4.1 实体类全局配置

  如果在配置文件指定实体类的全局配置,那么可以不需要再配置实体类的关联注解。
<!-- 2. 配置会话工厂 -->
    <bean name="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <!-- 指定数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <property name="globalConfig">
            <bean class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
                <!-- 
                    AUTO->`0`("数据库 ID 自增")
                    INPUT->`1`(用户输入 ID")
                    ID_WORKER->`2`("全局唯一 ID")
                    UUID->`3`("全局唯一 ID")
                    NONE-> 4 ("不需要 ID")
                 -->
                <property name="idType" value="0"></property>
                <!-- 实体类名与数据库表名的关联规则是,忽略前缀 -->
                <property name="tablePrefix" value="tb_"></property>
            </bean>
        </property>
    </bean>

 

实体类就可以去掉关联的注解了
package com.gjs.mybatisplus.pojo;

public class User {

</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Long id;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String name;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Integer age;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String email;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Long getId() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> id;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setId(Long id) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.id =<span style="color: rgba(0, 0, 0, 1)"> id;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getName() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> name;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setName(String name) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Integer getAge() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> age;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setAge(Integer age) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> age;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getEmail() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> email;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setEmail(String email) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.email =<span style="color: rgba(0, 0, 0, 1)"> email;
}

}

 

4.2. 插件配置

  Mybatis 默认情况下,是不支持物理分页的。默认提供的 RowBounds 这个分页是逻辑分页来的。
  逻辑分页:将数据库里面的数据全部查询出来后,在根据设置的参数返回对应的记录。(分页是在程序的内存中完成)。【表数据过多时,会溢出】
  物理分页:根据条件限制,返回指定的记录。(分页在数据库里面已经完成)
 
  MybatisPlus 是默认使用 RowBounds 对象是支持物理分页的。但是需要通过配置 Mybatis 插件来开启。
  配置:
<!-- 2. 配置会话工厂 -->
    <bean name="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <!-- 指定数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <property name="globalConfig">
            <bean class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
                <!-- 
                    AUTO->`0`("数据库 ID 自增")
                    INPUT->`1`(用户输入 ID")
                    ID_WORKER->`2`("全局唯一 ID")
                    UUID->`3`("全局唯一 ID")
                    NONE-> 4 ("不需要 ID")
                 -->
                <property name="idType" value="0"></property>
                <!-- 实体类名与数据库表名的关联规则是,忽略前缀 -->
                <property name="tablePrefix" value="tb_"></property>
            </bean>
        </property>
        <property name="plugins">
            <list>
                <!-- 分页的支持 -->
                <bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
                    <!-- 数据库方言  -->
                    <!-- 不同的数据库对 sql 标准未制定的功能不一样,比如分页,所以需要指定数据库方言 -->
                    <property name="dialectClazz" value="com.baomidou.mybatisplus.plugins.pagination.dialects.MySqlDialect"></property>
                </bean>
                <!-- 配置日志输出(SQL 语句) -->
                <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
                    <!-- 配置 sql 语句输出格式,true 为折叠,false 为平铺,不配默认为 false -->
                    <property name="format" value="true"></property>
                </bean>
            </list>
        </property>
    </bean>

 

  测试方法:
/**
     * 分页查询
     */
    @Test
    public void findPage() {
        try {
            List<User> users = userMapper.selectPage(new RowBounds(0, 5), null);
            for (User user : users) {System.out.println(user.getName());
            }
        } catch (Exception e) {e.printStackTrace();
        }
    }

 

 
回到顶部

5. 自定义方法

  MyBatis-Plus 只是在 MyBatis 的基础上做了增强,不做改变。所以 MyBatis-Plus 定义的基础方法不能满足需求时,可以通过 MyBatis 的语法定义方法,但最好不要用 MyBatis-Plus 以及定义的方法名。
回到顶部

 

回到顶部

6.Service 层

  MyBatis-Plus 不仅提供了持久层的基础通用方法,它还提供了一套业务层的通用方法。
  想要使用这些方法,只需让我们定义的 service 层的接口继承 MyBatis-Plus 定义的 IService 接口,并让实现类继承 MyBatis-Plus 定义的 ServiceImpl 类。
 
public interface UserService extends IService<User>{

}

 

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{

}

 

原文链接:https://www.cnblogs.com/gaojinshun/p/14545345.html