spring整合mybatisplus2.x详解

一丶Mp的配置文件

 1 xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:tx="http://www.springframework.org/schema/tx"
 6     xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
 7     xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
 8         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
10         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
11     
12     
13     
14     <context:property-placeholder location="classpath:db.properties"/>
15     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
16         <property name="driverClass" value="${jdbc.driver}">property>
17         <property name="jdbcUrl" value="${jdbc.url}">property>
18         <property name="user" value="${jdbc.username}">property>
19         <property name="password" value="${jdbc.password}">property>
20     bean>
21     
22     
23     <bean id="dataSourceTransactionManager" 
24         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
25         <property name="dataSource" ref="dataSource">property>
26     bean>
27     
28     <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
29     
30     
31     
35     <bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
36         
37         <property name="dataSource" ref="dataSource">property>
38         <property name="configLocation" value="classpath:mybatis-config.xml">property>
39         
40         <property name="typeAliasesPackage" value="com.atguigu.mp.beans">property>    
41         
42         
43         <property name="globalConfig" ref="globalConfiguration">property>
44     bean>
45     
46     
47     <bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
48         
49         <property name="dbColumnUnderline" value="true">property>
50         
51         
52         <property name="idType" value="0">property>
53         
54         
55         <property name="tablePrefix" value="tbl_">property>
56     bean>
57 58     
61     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
62         <property name="basePackage" value="com.atguigu.mp.mapper">property>
63     bean>
64     
65     
66 beans>

 


二丶CRUD的常用方法

2.1 Insert 方法

 1 /*
 2  * MybatisPlus会默认使用实体类的类名到数据中找对应的表.
 3  * 
 4  */
 5 //
 6 @TableName(value = "tbl_employee")
 7 public class Employee {
 8     /*
 9      * @TableId: value: 指定表中的主键列的列名, 如果实体属性名与列名一致,可以省略不指定. type: 指定主键策略.
10      */
11     //
12     @TableId(value = "id", type = IdType.AUTO)
13     private Integer id; // int
14     
15     //
16     @TableField(value = "last_name")
17     private String lastName;
18     private String email;
19     private Integer gender;
20     private Integer age;
21    
22     @TableField(exist = false)
23     //当数据库里面的表没有这个字段的时候,就不要写
24     private Double salary;
25 26 }

 

2.1.1 Insert (对象)

 1 @Test
 2     public void testCommonInsert1() {
 3  4         // 初始化Employee对象
 5         Employee employee = new Employee();
 6         employee.setLastName("MP");
 7         employee.setEmail("[email protected]");
 8         employee.setGender(1);
 9         employee.setAge(22);
10         employee.setSalary(20000.0);
11         // 插入到数据库
12         // insert方法在插入时, 会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中
13         Integer result = employeeMapper.insert(employee);
14 15         System.out.println("result: " + result);
16     }

 

2.1.2 insertAllColumn(对象)

 1  @Test
 2     public void testCommonInsert() {
 3  4         // 初始化Employee对象
 5         Employee employee = new Employee();
 6         employee.setLastName("MP");
 7         employee.setEmail("[email protected]");
 8         // employee.setGender(1);
 9         // employee.setAge(22);
10         employee.setSalary(20000.0);
11         // insertAllColumn方法在插入时, 不管属性是否非空, 属性所对应的字段都会出现到SQL语句中.
12         Integer result = employeeMapper.insertAllColumn(employee);
13         System.out.println("result: " + result);
14     }

 

2.1.3 获得主键

1       // 获取当前数据在数据库中的主键值
2         Integer key = employee.getId();
3         System.out.println("key:" + key);

 

2.2 Update 方法

2.2.1 updateById(对象)

 1  /**
 2      * 通用 更新操作
 3      */
 4     @Test
 5     public void testCommonUpdate() {
 6         // 初始化修改对象
 7         Employee employee = new Employee();
 8         employee.setId(7);
 9         employee.setLastName("小泽老师");
10         employee.setEmail("[email protected]");
11         employee.setGender(0);
12         Integer result = employeeMapper.updateById(employee);
13         System.out.println("result: " + result);
14     }

 

2.2.2 updateAllColumnById(对象)

 1  /**
 2      * 通用 更新操作
 3      */
 4     @Test
 5     public void testCommonUpdate() {
 6         // 初始化修改对象
 7         Employee employee = new Employee();
 8         employee.setId(7);
 9         employee.setLastName("小泽老师");
10         employee.setEmail("[email protected]");
11         employee.setGender(0);
12 13         Integer result = employeeMapper.updateAllColumnById(employee);
14         System.out.println("result: " + result);
15     }

 

2.3 Select 方法

2.3.1 selectById

    
1    // 1. 通过id查询
2         // Employee employee = employeeMapper.selectById(7);
3         // System.out.println(employee);

 

2.3.2 selectOne 

1    // 2. 通过多个列进行查询 id + lastName
2         // Employee employee = new Employee();
3         // //employee.setId(7);
4         // employee.setLastName("小泽老师");
5         // employee.setGender(0);
6         //
7         // Employee result = employeeMapper.selectOne(employee);
8         // System.out.println("result: " +result );
9         // 这个只能查一条数据,多的时候回报错

 

2.3.3 selectBatchIds

   
1    // 3. 通过多个id进行查询 
2         // List idList = new ArrayList<>();
3         // idList.add(4);
4         // idList.add(5);
5         // idList.add(6);
6         // idList.add(7);
7         // List emps = employeeMapper.selectBatchIds(idList);
8         // System.out.println(emps);

2.3.4 selectByMap 

1   // 4. 通过Map封装条件查询
2         // Map columnMap = new HashMap<>();
3         // columnMap.put("last_name", "Tom");
4         // columnMap.put("gender", 1);
5         //
6         // List emps = employeeMapper.selectByMap(columnMap);
7         // System.out.println(emps);

2.4 Delete 方法

2.4.1 deleteById   

1   // 1 .根据id进行删除
2         Integer result = employeeMapper.deleteById(13);
3         System.out.println("result: " + result);

 

2.4.2 deleteByMap      

1  // 2. 根据 条件进行删除
2         // Map columnMap = new HashMap<>();
3         // columnMap.put("last_name", "MP");
4         // columnMap.put("email", "[email protected]");
5         // Integer result = employeeMapper.deleteByMap(columnMap);
6         // System.out.println("result: " + result );

2.4.3 deleteBatchIds

      
1  // 3. 批量删除
2         // List idList = new ArrayList<>();
3         // idList.add(3);
4         // idList.add(4);
5         // idList.add(5);
6         // Integer result = employeeMapper.deleteBatchIds(idList);
7         // System.out.println("result: " + result );

 

三丶CRUD原理

  • employeeMapper 的本质 org.apache.ibatis.binding.MapperProxy

  • MapperProxy 中 sqlSession –>SqlSessionFactory

SqlSessionFacotry 中 → Configuration→ MappedStatements

每一个 mappedStatement 都表示 Mapper 接口中的一个方法与 Mapper 映射文件

中的一个 SQL。

MP 在启动就会挨个分析 xxxMapper 中的方法,并且将对应的 SQL 语句处理好,保

存到 configuration 对象中的 mappedStatements 中.

  • SqlSessionFacotry 中 → Configuration→ MappedStatements

每一个 mappedStatement 都表示 Mapper 接口中的一个方法与 Mapper 映射文件

中的一个 SQL。

MP 在启动就会挨个分析 xxxMapper 中的方法,并且将对应的 SQL 语句处理好,保

存到 configuration 对象中的 mappedStatements 中.

D. 本质:

Configuration: MyBatis 或者 MP 全局配置对象

MappedStatement:一个 MappedStatement 对象对应 Mapper 配置文件中的一个

select/update/insert/delete 节点,主要描述的是一条 SQL 语句

SqlMethod : 枚举对象 , MP 支持的 SQL 方法

TableInfo: 数据库表反射信息 ,可以获取到数据库表相关的信息

SqlSource: SQL 语句处理对象

MapperBuilderAssistant: 用于缓存、 SQL 参数、查询方剂结果集处理等.

通过 MapperBuilderAssistant 将每一个 mappedStatement

添加到 configuration 中的 mappedstatements中

四丶条件构造器

查询方式 说明
setSqlSelect 设置 SELECT 查询字段
where WHERE 语句,拼接 + WHERE 条件
and AND 语句,拼接 + AND 字段=值
andNew AND 语句,拼接 + AND (字段=值)
or OR 语句,拼接 + OR 字段=值
orNew OR 语句,拼接 + OR (字段=值)
eq 等于=
allEq 基于 map 内容等于=
ne 不等于<>
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=
like 模糊查询 LIKE
notLike 模糊查询 NOT LIKE
in IN 查询
notIn NOT IN 查询
isNull NULL 值查询
isNotNull IS NOT NULL
groupBy 分组 GROUP BY
having HAVING 关键词
orderBy 排序 ORDER BY
orderAsc ASC 排序 ORDER BY
orderDesc DESC 排序 ORDER BY
exists EXISTS 条件语句
notExists NOT EXISTS 条件语句
between BETWEEN 条件语句
notBetween NOT BETWEEN 条件语句
addFilter 自由拼接 SQL
last 拼接在最后,例如:last("LIMIT 1")
  • 官方示例

     1 @Test
     2 public void testTSQL11() {
     3     /*
     4      * 实体带查询使用方法  输出看结果
     5      */
     6     EntityWrapper ew = new EntityWrapper();
     7     ew.setEntity(new User(1));
     8     ew.where("user_name={0}", "'zhangsan'").and("id=1")
     9             .orNew("user_status={0}", "0").or("status=1")
    10             .notLike("user_nickname", "notvalue")
    11             .andNew("new=xx").like("hhh", "ddd")
    12             .andNew("pwd=11").isNotNull("n1,n2").isNull("n3")
    13             .groupBy("x1").groupBy("x2,x3")
    14             .having("x1=11").having("x3=433")
    15             .orderBy("dd").orderBy("d1,d2");
    16     System.out.println(ew.getSqlSegment());
    17 }
    18 int buyCount = selectCount(Condition.create()
    19                 .setSqlSelect("sum(quantity)")
    20                 .isNull("order_id")
    21                 .eq("user_id", 1)
    22                 .eq("type", 1)
    23                 .in("status", new Integer[]{0, 1})
    24                 .eq("product_id", 1)
    25                 .between("created_time", startDate, currentDate)
    26                 .eq("weal", 1));

     

  • 自定义的SQL怎么使用

     1 List selectMyPage(RowBounds rowBounds, @Param("ew") Wrapper wrapper);
     2 
     8 /**
     9 10 - 用户登录次数
    11 */
    12 @Select("")
    13 List findUserLogin(@Param("ew") Wrapper wrapper);
    14 15 /**
    16 17 - 用户在线时长
    18 */
    19 @Select("")
    20 List findUserOnline(@Param("ew") Wrapper wrapper);

常用的用法:

spring整合mybatisplus2.x详解_第1张图片

delete、selectCount、selectList、selectMaps、selectObjs、update。。。。

五丶ActiveRecord(活动记录)

5.1 java类继承

1 public class Employee extends Model {
2     private Integer id; // int
3     private String lastName;
4     private String email;
5     private Integer gender;
6     private Integer age;
7 }

 

5.2继承BaseMapper

1 public interface EmployeeMapper extends BaseMapper {
2     //   Integer  insertEmployee(Employee employee );
3     //    SQL...
4 }

 

5.3 测试类

 1 /**
 2      * AR 修改操作
 3      */
 4     @Test
 5     public void testARUpdate() {
 6         Employee employee = new Employee();
 7         employee.setId(20);
 8         employee.setLastName("宋老湿");
 9         employee.setEmail("[email protected]");
10         employee.setGender(1);
11         employee.setAge(36);
12 13         boolean result = employee.updateById();
14         System.out.println("result:" + result);
15 16     }
17 18     /**
19      * AR 插入操作
20      */
21     @Test
22     public void testARInsert() {
23         Employee employee = new Employee();
24         employee.setLastName("宋老师");
25         employee.setEmail("[email protected]");
26         employee.setGender(1);
27         employee.setAge(35);
28 29         boolean result = employee.insert();
30         System.out.println("result:" + result);
31     }
32 /**
33      * AR 分页复杂操作
34      */
35     @Test
36     public void testARPage() {
37 38         Employee employee = new Employee();
39 40         Page page = employee.selectPage(new Page<>(1, 1),
41                 new EntityWrapper().like("last_name", "老"));
42         List emps = page.getRecords();
43         System.out.println(emps);
44     }

七丶插件原理

 1 
 2         
 3             
 4                 
 5             class="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
 6                 
 7                 class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
 8                     
 9                 
10                 
11                 
12                 class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
13                     
14                     
15                 
16                 
17                 
18         class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor">
19                 
20             
21             
22             
23         

7.1分页插件

 1   /**
 2      * 测试分页插件
 3      */
 4     @Test
 5     public void testPage() {
 6  7         Page page = new Page<>(1, 1);
 8  9         List emps = employeeMapper.selectPage(page, null);
10         System.out.println(emps);
11 12         System.out.println("===============获取分页相关的一些信息======================");
13 14         System.out.println("总条数:" + page.getTotal());
15         System.out.println("当前页码: " + page.getCurrent());
16         System.out.println("总页码:" + page.getPages());
17         System.out.println("每页显示的条数:" + page.getSize());
18         System.out.println("是否有上一页: " + page.hasPrevious());
19         System.out.println("是否有下一页: " + page.hasNext());
20 21         // 将查询的结果封装到page对象中
22         page.setRecords(emps);
23         List records = page.getRecords();
24         System.out.println(records);
25 26     }

 

7.2分析插件

1 /**
2      * 测试SQL执行分析插件,执行全表删除的会报错
3      */
4     @Test
5     public void testSQLExplain() {
6 7         employeeMapper.delete(null); // 全表删除
8     }

 

7.3性能分析插件

 1 /**
 2      * 测试 性能分析插件
 3      */
 4     @Test
 5     public void testPerformance() {
 6         Employee employee = new Employee();
 7         employee.setLastName("玛利亚老师");
 8         employee.setEmail("[email protected]");
 9         employee.setGender("0");
10         employee.setAge(22);
11 12         employeeMapper.insert(employee);
13 14     }

 spring整合mybatisplus2.x详解_第2张图片

7.4 乐观锁插件

 1 @Test
 2     public void testOptimisticLocker() {
 3         // 更新操作
 4         Employee employee = new Employee();
 5         employee.setId(15);
 6         employee.setLastName("TomAA");
 7         employee.setEmail("[email protected]");
 8         employee.setGender("1");
 9         employee.setAge(22);
10         employee.setVersion(3);
11 12         employeeMapper.updateById(employee);
13 14     }
15 16  @Version
17  private Integer version ;

 

7.5概述

1) 插件机制:
Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求, 完
成相关数据的动态改变。
Executor
StatementHandler
ParameterHandler
ResultSetHandler
2) 插件原理
四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll(),会经过每个插
件对象的 plugin()方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四
大对象相关方法的执行,因为要执行四大对象的方法需要经过代理.
7.2 分页插件
1) com.baomidou.mybatisplus.plugins.PaginationInterceptor
7.3 执行分析插件
1) com.baomidou.mybatisplus.plugins.SqlExplainInterceptor
2) SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本
3) 该插件的作用是分析 DELETE UPDATE 语句,防止小白
或者恶意进行 DELETE UPDATE 全表操作
4) 只建议在开发环境中使用,不建议在生产环境使用
5) 在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,
根据结果集中的 Extra 列来断定当前是否全表操作。
7.4 性能分析插件
1) com.baomidou.mybatisplus.plugins.PerformanceInterceptor
2) 性能分析拦截器,用于输出每条 SQL 语句及其执行时间java 课程系列
3) SQL 性能执行分析,开发环境使用, 超过指定时间,停止运行。有助于发现问题
7.5 乐观锁插件
1) com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor
2) 如果想实现如下需求: 当要更新一条记录的时候,希望这条记录没有被别人更新
3) 乐观锁的实现原理:
取出记录时,获取当前 version 2
更新时,带上这个 version 2
执行更新时, set version = yourVersion+1 where version = yourVersion
如果 version 不对,就更新失败
4) @Version 用于注解实体字段,必须要有。
 

 spring整合mybatisplus2.x详解_第3张图片

 spring整合mybatisplus2.x详解_第4张图片

 

 spring整合mybatisplus2.x详解_第5张图片

 spring整合mybatisplus2.x详解_第6张图片

 spring整合mybatisplus2.x详解_第7张图片

 spring整合mybatisplus2.x详解_第8张图片

 spring整合mybatisplus2.x详解_第9张图片

 spring整合mybatisplus2.x详解_第10张图片

 spring整合mybatisplus2.x详解_第11张图片

 spring整合mybatisplus2.x详解_第12张图片

spring整合mybatisplus2.x详解_第13张图片

 

八丶其他配置

 1 
 2     class="com.atguigu.mp.injector.MySqlInjector">
 3     
 4     
 5     class="com.baomidou.mybatisplus.mapper.LogicSqlInjector">
 6     
 7     
 8     class="com.atguigu.mp.metaObjectHandler.MyMetaObjectHandler"> 
 9     
10     
11     class="com.baomidou.mybatisplus.incrementer.OracleKeyGenerator">
12 13 
14 15         
18         
19         
20         
21         
22         
23         
24         
25         
26         
27         
28         
29         

 

8.1 自定义全局操作

8.1.1 在 Mapper 接口中定义相关的 CRUD 方法

 1 /**
 2  * 

3 * Mapper 接口 4 *

5 * 6 * @author weiyunhui 7 * @since 2018-06-21 8 */ 9 public interface EmployeeMapper extends BaseMapper { 10 11 int deleteAll(); 12 }

 

8.1.2扩展 AutoSqlInjector inject 方法,实现 Mapper 接口中方法要注入的 SQL

 1 public class MySqlInjector  extends AutoSqlInjector{
 2     
 3     /**
 4      * 扩展inject 方法,完成自定义全局操作
 5      */
 6     @Override
 7     public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class  ,
 8             Class modelClass, TableInfo table) {
 9         //将EmployeeMapper中定义的deleteAll, 处理成对应的MappedStatement对象,加入到configuration对象中。
10         
11         //注入的SQL语句
12         String sql = "delete from " +table.getTableName();
13         //注入的方法名   一定要与EmployeeMapper接口中的方法名一致
14         String method = "deleteAll" ;
15         
16         //构造SqlSource对象
17         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
18         
19         //构造一个删除的MappedStatement
20         this.addDeleteMappedStatement(mapperClass, method, sqlSource);
21         
22     }
23 }

 

8.1.3 在 MP 全局策略中,配置 自定义注入器

    <property name="sqlInjector" ref="mySqlInjector">property>

启动的时候会把deleteAll添加进去了

8.2 逻辑删除

1) com.baomidou.mybatisplus.mapper.LogicSqlInjector
2) logicDeleteValue 逻辑删除全局值
3) logicNotDeleteValue 逻辑未删除全局值
4) 在 POJO 的逻辑删除字段 添加 @TableLogic 注解
5) 会在 mp 自带查询和更新方法的 sql 后面,追加『逻辑删除字段』=『LogicNotDeleteValue
默认值』 删除方法: deleteById()和其他 delete 方法, 底层 SQL 调用的是 update tbl_xxx
set 『逻辑删除字段』 =『logicDeleteValue 默认值』

 

8.2.1 xml配置

1 
2     class="com.baomidou.mybatisplus.mapper.LogicSqlInjector">
3 
4         
5 
6         
7         

 

8.2.2添加注解

1 @TableLogic   // 逻辑删除属性
2     private Integer logicFlag ;

 

8.2.3 方法

 1    /**
 2      * 测试逻辑删除
 3      */
 4     @Test
 5     public void testLogicDelete() {
 6         
 7 //      Integer result = userMapper.deleteById(1);
 8 //      System.out.println("result:" +result );
 9         User user = userMapper.selectById(1);
10         System.out.println(user);
11     }

 spring整合mybatisplus2.x详解_第14张图片

 spring整合mybatisplus2.x详解_第15张图片

 spring整合mybatisplus2.x详解_第16张图片

 spring整合mybatisplus2.x详解_第17张图片

 spring整合mybatisplus2.x详解_第18张图片

 spring整合mybatisplus2.x详解_第19张图片

 spring整合mybatisplus2.x详解_第20张图片

 spring整合mybatisplus2.x详解_第21张图片

8.3公共字段填充

8.3.1继承类重写方法

 1 /**
 2  * 自定义公共字段填充处理器
 3  */
 4 public class MyMetaObjectHandler extends MetaObjectHandler {
 5  6     /**
 7      * 插入操作 自动填充
 8      */
 9     @Override
10     public void insertFill(MetaObject metaObject) {
11         // 获取到需要被填充的字段的值
12         Object fieldValue = getFieldValByName("name", metaObject);
13         if (fieldValue == null) {
14             System.out.println("*******插入操作 满足填充条件*********");
15             setFieldValByName("name", "weiyunhui", metaObject);
16         }
17 18     }
19 20     /**
21      * 修改操作 自动填充
22      */
23     @Override
24     public void updateFill(MetaObject metaObject) {
25         Object fieldValue = getFieldValByName("name", metaObject);
26         if (fieldValue == null) {
27             System.out.println("*******修改操作 满足填充条件*********");
28             setFieldValByName("name", "weiyh", metaObject);
29         }
30     }
31 32 }

 

8.3.2注解填充字段 @TableFile(fill = FieldFill.INSERT) 查看 FieldFill

@TableField(fill=FieldFill.INSERT_UPDATE)
    private String name ;

 

8.3.3 MP 全局注入 自定义公共字段填充处理器

 1 
 2         
 3 测试方法
 4 
 5     /**
 6      * 测试公共字段填充
 7      */
 8     @Test
 9     public void testMetaObjectHandler() {
10         User user = new User();
11         //user.setName("Tom");
12         
13         user.setId(5);
14         user.setLogicFlag(1);
15         
16         userMapper.updateById(user);
17     }

 

8.4Oracle序列

8.4.1实体类配置主键 Sequence @KeySequence

1 //@KeySequence(value="seq_user",clazz=Integer.class)
2 public class User extends Parent {
3     //@TableId(type=IdType.INPUT)
4     private Integer id  ;

 

8.4.2 全局 MP 主键生成策略为 IdType.INPUT

   
    

 

8.4.3全局 MP 中配置 Oracle 主键 Sequence


 

8.4.4 写一个父类

1 @KeySequence(value="seq_user",clazz=Integer.class)
2 public abstract class Parent {
3 4 }

 

 

 

你可能感兴趣的:(spring整合mybatisplus2.x详解)