浅谈MyBatis-Plus学习之插件扩展


一、Mybatis插件机制

mybatis通过插件(Interceptor)对相关目标对象(四大对象)进行动态代理,完成相关数据的变更,从而提供更多功能。

在这里不介绍其内部实现,仅仅介绍MP所提供的相关插件。

二、MP插件介绍

2.1、分页插件

好像MP已经在BaseMapper中提供了相关分页方法selectPage,为什么还要使用分页插件呢?

这是因为selectPage通过ibatis的RowBounds进行分页, 也就是在内存中进行分页 ,所以不推荐

而分页插件的使用,是在相关的查询语句后面添加Limit关键字,从而实现物理分页

applicationContext.xml

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property>
        <property name="globalConfig" ref="globalConfiguration"></property>

        <!-- 注入插件 -->
        <property name="plugins">
            <list>
              <!-- 分页插件 -->
              <bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>            
            </list>
        </property>
    </bean>

测试代码如下

/**
     * 分页插件测试使用
     */
    @Test
    public void testPaginate() {
        Page<Employee> page = new Page<>(1, 3);
        List<Employee> emps = employeeMapper.selectPage(page, null);  //FROM tbl_employee LIMIT 0,3 
        System.out.println(emps);

        System.out.println("==========获取分页相关信息=============");
        System.out.println("总条数:" + page.getTotal());
        System.out.println("总页数:" + page.getPages());
        System.out.println("当前页码:" + page.getCurrent());
        System.out.println("每页显示条数:" + page.getSize());
        System.out.println("是否有上一页:" + page.hasPrevious());
        System.out.println("是否有下一页:" + page.hasNext());
        //封装当前页数据到Page对象中
        page.setRecords(emps);
    }

Page用于封装分页相关参数

2.2、执行分析插件

SQL的执行分析插件,目前只支持MYSQL5.6.3以上版本

该作用主要分析DELETE以及UPDATE的语句是否是进行全表操作。

本质是在SQL语句前面拼接Explain关键字,从而分析要执行的SQL语句

判断结果的Extra列来判断是否全表操作

applicationContext.xml

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property>
        <property name="globalConfig" ref="globalConfiguration"></property>

        <!-- 注入插件 -->
        <property name="plugins">
            <list>
              <!-- 执行分析插件 ,不推荐生产环境使用-->
              <bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
                      <!-- stopProceed 发现执行全表 delete update 语句是否停止执行 -->
                      <property name="stopProceed" value="true"></property>
              </bean>          
            </list>
        </property>
    </bean>

测试代码如下

/**
     * 执行分析插件测试使用 
     * 本质通过 Explain这个SQL关键字分析执行的SQL
     */
    @Test(expected=Exception.class)
    public void testSqlExplain() {
        employeeMapper.delete(null); //全表删除
    }

2.3、性能分析插件

主要用于输出SQL语句以及其执行时间,可以设置其超过指定时间,停止运行

不推荐生产环境中使用

applicationContext.xml

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property>
        <property name="globalConfig" ref="globalConfiguration"></property>

        <!-- 注入插件 -->
        <property name="plugins">
            <list>
              <!-- 性能分析插件 -->
              <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
                      <property name="format" value="true"></property>
                      <!-- 设置最大执行时间,超过则报错,提示优化,但是SQL一样成功执行 -->
                      <!-- <property name="maxTime" value="100000"></property> -->
              </bean>             
            </list>
        </property>
    </bean>

2.4、乐观锁插件

乐观锁插件所要做的事情就是:

1、取出记录时,会带上当前版本version值

2、然后更新的时候会将自己的version值跟数据库记录的version值比较

如果相等,则执行更新操作,并将version+1;如果不等,则更新失败

其实实现的需求就是希望在更新记录的时候,希望这条记录没有给其他人更新过

注意:使用乐观锁插件,需要使用@Version注解实体字段,并且数据库中也要有对应映射字段

@TableName("tbl_employee")
public class Employee extends Model<Employee> {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    private String lastName;
    private String email;
    private String gender;
    private Integer age;
    @Version
    private Integer version;

applicationContext.xml

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property>
        <property name="globalConfig" ref="globalConfiguration"></property>

        <!-- 注入插件 -->
        <property name="plugins">
            <list>
              <!-- 乐观锁插件 -->
              <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"></bean>              
            </list>
        </property>
    </bean>


原文链接:https://www.cnblogs.com/jayhou/p/9824571.html