• 使用SQL注入器就可以自定义例如selectById的默认方法。

    实现步骤
    Step1:创建定义方法的类;
    Step2:创建注入器;
    Step3:在Mapper中加入自定义方法。

    自定义注入器的简单使用

    第一步:创建定义方法的类

    public class DeleteAllMethod  extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    //执行的SQL
    String sql = "delete from " + tableInfo.getTableName();
    //mapper接口方法名
    String method = "deleteAll";
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
    return addDeleteMappedStatement(mapperClass, method, sqlSource);
    }
    }

    第二步:创建注入器

    @Component
    public class MySqlInjector extends DefaultSqlInjector { @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
    //MP自定义的SQL语句,如果不添加,MP自定义的语句就不能用了
    List<AbstractMethod> methodList = super.getMethodList(mapperClass);
    methodList.add(new DeleteAllMethod());
    return methodList;
    } }

    DefaultSqlInjector、AbstractSqlInjector、ISqlInjector都能继承。

    第三步:在UserMapper中加入自定义方法deleteAll

        /**
    * 删除所有数据
    * @return 影响行数
    */
    int deleteAll();

    第四步:测试

        @Test
    public void deleteAll() {
    userMapper.deleteAll();
    }

    结果如下:

    这里需要注意:

    1. 不知道大家还记不记得之前逻辑删除,3.1.2之前的版本配置了一个SQL注入器。自定义SQL注入器不可以和逻辑删除一起配置,因为不能同时制定两个sql注入器,所以报错。有一个办法就是MySqlinjector不要继承DefaultSqlInjector直接继承LogicSqlInjector就可以了,这样配置这一个sql注入器,就既能使用逻辑删除又能加入自定义方法了。

    2. 如果报以下错误

    当删除所有数据时,由于有的数据行有外键的约束,不允许你进行物理删除。使用语句删除外键即可,alter table user drop foreign key manager_fk;。或者把外键字段原来默认的Restrict改成CASCADE。

    同时附上初始化数据语句,可以多次尝试

    #初始化数据:
    INSERT INTO user (id, name, age, email, manager_id
    , create_time)
    VALUES (1087982257332887553, '大boss', 40, 'boss@baomidou.com', NULL
    , '2019-01-11 14:20:20'),
    (1088248166370832385, '王天风', 25, 'wtf@baomidou.com', 1087982257332887553
    , '2019-02-05 11:12:22'),
    (1088250446457389058, '李艺伟', 28, 'lyw@baomidou.com', 1088248166370832385
    , '2019-02-14 08:31:16'),
    (1094590409767661570, '张雨琪', 31, 'zjq@baomidou.com', 1088248166370832385
    , '2019-01-14 09:15:15'),
    (1094592041087729666, '刘红雨', 32, 'lhm@baomidou.com', 1088248166370832385
    , '2019-01-14 09:48:16');

    优化

    如果每张表都需要删除全部,那我们为每个Mapper都写一个deleteAll()方法,非常的繁琐。这时候我们可以自己建立一个MyMapper接口,MyMapper接口继承BaseMapper,而类似于UserMapper的自定义Mapper全部继承MyMapper,这样我们就只需要在MyMapper中编写一个deleteAll方法,再由UserMpper和其他Mapper继承就可以实现deleteAll()方法的重用。

    选装件InsertBatchSomeColumn

    选择件其实也是自定义SQL注入器,但是是由官方提供的。InsertBatchSomeColumn的主要功能是批量新增数据,自选字段insert。接下来让我们看看是如何实现的吧。
    第一步:注入器中加入方法

        @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
    //MP自定义的SQL语句,如果不添加,MP自定义的语句就不能用了
    List<AbstractMethod> methodList = super.getMethodList(mapperClass);
    methodList.add(new DeleteAllMethod());
    //加入选装件InsertBatchSomeColumn,同时排除逻辑删除字段
    methodList.add(new InsertBatchSomeColumn(t->!t.isLogicDelete()));
    return methodList;
    }

    第二步:在MyMapper中加入insertBatchSomeColumn方法

    public interface MyMapper<T> extends BaseMapper<T> {
    /**
    * 删除所有数据
    * @return 影响行数
    */
    int deleteAll(); int insertBatchSomeColumn(List<T> list);
    }

    第三步:测试

     @Test
    public void insertBatchSomeColumn() { User user = new User();
    user.setName("王聚义");
    user.setAge(26);
    user.setEmail("wjy@163.com");
    user.setManagerId(1088248166370832385L); User user2 = new User();
    user2.setName("王收义");
    user2.setAge(28);
    user2.setEmail("wsy@163.com");
    user2.setManagerId(1088248166370832385L); List<User> list = new ArrayList<>();
    list.add(user);
    list.add(user2); userMapper.insertBatchSomeColumn(list);
    }

    可以看出批量插入成功。

    需要注意的是,User对象中为Null的值会覆盖没有被排除字段的默认值。例如version的默认值为1,但是我们插入的User的version为null,如果version这个字段在注入器组件中没有被排除,结果数据库中的值应该为null。

    同时作者在注解中也提示,选装器只在mysql中测试过,所以慎用。

    选装件LogicDeleteByIdWithFill

    LogicDeleteByIdWithFill的主要功能是根据id逻辑删除数据并带字段填充功能。例如在删除的时候需要添加操作人。

    第一步:注入器中加入方法

     methodList.add(new LogicDeleteByIdWithFill());

    第二步:在MyMapper中加入方法

        int deleteByIdWithFill(T entity);

    第三步:测试

     @Test
    public void deleteByIdWithFill() {
    User user = new User();
    user.setId(1346432120618147841L);
    user.setUpdateTime(LocalDateTime.now());
    userMapper.deleteByIdWithFill(user);
    }

    注意,如果想在删除的同时修改数据,被修改的数据必须有自动填充标识,不然无法完成更新。结果如下:

    选装件AlwaysUpdateSomeColumnById

    AlwaysUpdateSomeColumnById的主要功能是根据id更新固定的某些字段。

    第一步:注入器中加入方法

            methodList.add(new AlwaysUpdateSomeColumnById(t->!t.getColumn().equals("name")));

    第二步:在MyMapper中加入方法

     int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);

    第三步:测试

        @Test
    public void alwaysUpdateSomeColumnById() {
    User user = new User();
    user.setId(1346432120618147841L);
    user.setName("王地风");
    user.setAge(16);
    userMapper.alwaysUpdateSomeColumnById(user);
    }

    结果如下:

  • 相关阅读:

【Mybatis-Plus进阶学习(八)】SQL注入器的更多相关文章

  1. Mybatis基础进阶学习2

    Mybatis基础进阶学习2 1.测试基本结构 2.三个POJO package com.pojo; import java.io.Serializable; import java.util.Dat ...

  2. Java数据持久层框架 MyBatis之API学习八(Java API详解)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  3. 【译】SQL Server索引进阶第八篇:唯一索引

    原文:[译]SQL Server索引进阶第八篇:唯一索引     索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就 ...

  4. (转)MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql

    http://blog.csdn.net/yerenyuan_pku/article/details/71893689 前面对MyBatis框架的学习中,我们对Mapper.xml映射文件多少有些了解 ...

  5. mybatis源码学习:基于动态代理实现查询全过程

    前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...

  6. mybatis源码学习--spring+mybatis注解方式为什么mybatis的dao接口不需要实现类

    相信大家在刚开始学习mybatis注解方式,或者spring+mybatis注解方式的时候,一定会有一个疑问,为什么mybatis的dao接口只需要一个接口,不需要实现类,就可以正常使用,笔者最开始的 ...

  7. Java数据持久层框架 MyBatis之API学习一(简介)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  8. Mybatis 源码学习系列

    前言 很久以前,我们学习了Java,从一个控制台的 Hello world .开始,我们进入了面向对象的世界. 然后由学习了SQL语言,可以写出SQL语句来将尘封在硬盘之下的数据库数据,展现出来. 后 ...

  9. MyBatis基础入门《八》查询参数传入Map

    MyBatis基础入门<八>查询参数传入Map 描述: 在执行select查询数据的时候,方法传入的参数是java.util.Map类型. 接口方法: xml文件 注意: 书写SQL语句的 ...

  10. SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

随机推荐

  1. Nodejs C++插件(N-API)

    Nodejs C++插件(N-API) 0. 环境搭建 1. JS中调用C++方法 1.1 JS中调用源文件的C++方法 1.2 JS中调用动态库的C++方法 2. C++中调用JS方法 2.1. C ...

  2. 数据库周刊59丨GaussDB(for openGauss)开放商用;人大金仓保障冬奥会演练顺利完成;MDL锁导致的MySQL问题分析;PG日志使用手册;达梦表空间查询;数据库笔试题面试题集……

    热门资讯 1.openGauss 上线华为云正式商用 - GaussDB(for openGauss) [摘要]近日,GaussDB(for openGauss)已于华为云官网全面开放商用.该产品是华 ...

  3. dotnet 委托delegate的使用 定义和使用

    void Main() { // 委托 - 初级和高级的分水岭 // 1. 委托的初体验 // 委托是一个引用类型,其实是一个类型,保存方法的指针(地址) (变量名字都是地址 都是指针) // 是一个 ...

  4. 2. 王道OS-操作系统的特征,发展和分类

    1. 并发:宏观上是同时发生的,微观是交替发生的 :ps:并行:宏观和微观都是同时发生的 : ps:单核CPU同一时刻只能执行一个程序,各个程序只能并发的执行 : 多核CPU同一时刻可以同时执行多个程 ...

  5. iframe嵌套PMM2.0

    1.首先进入容器中 docker exec -it pmm-server /bin/bash 2.修改grafana.ini,允许匿名登录 vim /etc/grafana/grafana.ini 然 ...

  6. python使用协程完成批量模拟支付

    import asyncio import sys from queue import Queue sys.path.append("../") # from tool.__ini ...

  7. SpringMvc请求注解@RequestBody请求体/@PathVaribale/@RequestParam【支持Ajax】

    一.@RequestBody请求体 注意请求体只有form表单才有,而对于链接来说不使用 1).在Controller中写 @RequestBody String body是基本用法 另外可以封装对象 ...

  8. php 对二维数组按照汉字首字母排序

    1 /** 2 * 取汉字的第一个字的首字母 3 * @param type $str 4 * @return string|null 5 */ 6 function _getFirstCharter ...

  9. 腾讯云禁止root用户登录

    背景 买了腾讯云的云主机服务,装的 OpenCloudOS 系统,结果没几天就提示异常登录和恶意文件.结果还改了我的密码,导致我xshell登陆不了,通过腾讯云后台登进去发现有挖矿病毒,但还没完全跑起 ...

  10. 在线激活win

    目前DragonKMS神龙版能激活win11.win10.win8/8.1.win7以及server2008/2012/2016/2019/2022等系统版本,其中包括:专业工作站版.企业版.专业版. ...