zoukankan      html  css  js  c++  java
  • MybatisPlus学习笔记9:自定义全局操作

    1、AutoSqlInjector :

    BaseMapper提供了17个常用方法,但是有些需求这些方法还是不能很好的实现,那么怎么办呢?
    大家肯定会想到是在xml文件中写sql语句解决。
    这样确实可以,因为MP是只做增强不做改变,我们完全可以按照mybatis的原来的方式来解决。
    不过MP也提供了另一种解决办法,那就是自定义全局操作。
    所谓自定义全局操作,也就是我们可以在mapper中自定义一些方法,然后通过某些操作,让自定义的这个方法也能像BaseMapper的内置方法,供全局调用。
    接下来就看看如何实现(以deleteAll方法为例)。

    1.1在mapper中定义方法

    public interface EmplopyeeDao extends BaseMapper<Employee> {
        int deleteAll();
    }
    
    public interface UserDao extends BaseMapper<User> {
        int deleteAll();
    }
    

    在这两个mapper接口中都定义了deleteAll方法。

    1.2 编写自定义注入类

    该类继承AutoSqlInjector,重写inject方法。
    然后编写sql语句,指定mapper接口中的方法,最后调用addDeleteMappedStatement方法即可。

    public class MySqlInjector extends AutoSqlInjector {
        @Override
        public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, 
                                  Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
            /* 添加一个自定义方法 */
            deleteAllUser(mapperClass, modelClass, table);
            System.out.println(table.getTableName());
        }
    
        public void deleteAllUser(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
            /* 执行 SQL ,动态 SQL 参考类 SqlMethod */
            String sql = "delete from " + table.getTableName();
            /* mapper 接口方法名一致 */
            String method = "deleteAll";
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
            this.addDeleteMappedStatement(mapperClass, method, sqlSource);
        }
    }
    

    1.3 在Spring文件中配置

    先把刚才自定义的类注册成bean,然后在全局策略配置的bean中引用自定义类的bean即可。

    <!-- 定义自定义注入器 -->
    <bean class="com.zhu.mybatisplus.injector.MySqlInjector" id="mySqlInjector"/>
    ..........
    <!-- 5、mybatisplus的全局策略配置 -->
        <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
            <property name="idType" value="0"/>
            <property name="tablePrefix" value="tb_"/>
            <!-- 注入自定义全局操作 -->
            <property name="sqlInjector" ref="mySqlInjector"/>
        </bean>
    

    1.4 测试

    经测试,当userDao调用deleteAll方法时,会删除tb_user表的所有数据,employeeDao调用deleteAll方法时,会删除tb_employee表的所有数据。
    说明deleteAll方法是有效的。
    不过在运行这两个测试时,由于是全表删除操作,所有要先把执行分析插件关了。

    @Test
    public void testMySqlInjector(){
        Integer result = userDao.deleteAll();
        System.out.println(result);
    }
    
    @Test
    public void testMySqlInjector2(){
        Integer result = emplopyeeDao.deleteAll();
        System.out.println(result);
    }
    

    2、逻辑删除

    其实数据并不会轻易的删除掉,毕竟数据收集不易,所以就有了逻辑删除。
    逻辑删除: 并不会真正的从数据库中将数据删除掉,而是将当前被删除的这条数据中的一个逻辑删除字段置为删除状态,
    比如该数据有一个字段logic_flag,当其值为1表示未删除,值为-1表示删除,那么逻辑删除就是将1变成-1。

    2.1 数据表

    在数据表中需要添加逻辑删除字段(logic_flag)

    2.2 实体类

    数据库中逻辑删除字段是logic_flag,所以实体类中的logicFlag需要用@TableLogic注解标记。

    @Data
    public class User{
        private Integer id;
        private String name;
        private Integer age;
        private Integer gender;
        @TableLogic //标记逻辑删除属性
        private Integer logicFlag;
    }
    

    2.3 mapper

    public interface UserDao extends BaseMapper<User> {
    }
    

    2.4 需要在spring-dao.xml中做如下配置:

    首先定义逻辑删除的bean:

    <!-- 逻辑删除 -->
    <bean class="com.baomidou.mybatisplus.mapper.LogicSqlInjector" id="logicSqlInjector"/>
    再在全局配置的bean中注入逻辑删除以及逻辑删除值:
    
    
    <!-- 5、mybatisplus的全局策略配置 -->
        <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
            <!-- 此处省略其他全局配置 -->
            <!-- 注入自定义全局操作,做逻辑删除时需要先注释掉 -->
            <!--<property name="sqlInjector" ref="mySqlInjector"/>-->
    
            <!-- 注入逻辑删除,先要把自定义的注释掉 -->
            <property name="sqlInjector" ref="logicSqlInjector"/>
            <!-- 注入逻辑删除值 -->
            <property name="logicDeleteValue" value="-1"/><!-- -1是删除状态 -->
            <property name="logicNotDeleteValue" value="1"/><!-- 1是未删除状态 -->
        </bean>
    
    

    因为逻辑删除实际上也是一个sqlInjector,所以先要把刚才做自定义全局操作时注入的自定义全局操作注释掉,上面代码中已有详细注释说明。

    2.5 测试

    @Test
        public void testLogicDelete(){
            Integer result = userDao.deleteById(1);
            System.out.println(result);
            //User user = userDao.selectById(1);
            //System.out.println(user);
        }
    

    运行该测试,执行删除操作的时候,真正执行的sql语句是UPDATE tb_user SET logic_flag=-1 WHERE id=?,就是把逻辑删除字段的值设置为-1;
    当逻辑删除字段的值是-1时再执行查询操作,sql是SELECT ... FROM tb_user WHERE id=? AND logic_flag=1,所以查询结果是null。

  • 相关阅读:
    RN 各种小问题
    迷宫问题的求解(回溯法、深度优先遍历、广度优先遍历)
    java 对象的初始化流程(静态成员、静态代码块、普通代码块、构造方法)
    java四种访问权限
    八大排序之归并排序
    八大排序之堆排序
    八大排序之选择排序
    八大排序之快速排序
    Java动态代理和cglib动态代理
    类加载器 ClassLoder详解
  • 原文地址:https://www.cnblogs.com/xidianzxm/p/12709043.html
Copyright © 2011-2022 走看看