Mybatis-Plus如何自定义SQL注入器?

有关Mybatis-Plus常用功能之前有做过一篇总结:

Mybatis-Plus如何自定义SQL注入器?

MyBatisPlus常用功能总结!(附项目示例)

一、什么是SQL注入器

我们在使用Mybatis-Plus时,dao层都会去继承BaseMapper接口,这样就可以用BaseMapper接口所有的方法,

BaseMapper中每一个方法其实就是一个SQL注入器

在Mybatis-Plus的核心(core)包下,提供的默认可注入方法有这些:

Mybatis-Plus如何自定义SQL注入器?

那如果我们想自定义SQL注入器呢,我们该如何去做?

比如在Mybatis-Plus中调用updateById方法进行数据更新默认情况下是不能更新空值字段的。

而在实际开发过程中,往往会遇到需要将字段值更新为空值的情况。

那如何让Mybatis-Plus支持空值更新呢?

如果仅是想实现支持更新空值字段并不需要我们自定义SQL注入器,因为Mybatis-Plus提供了几个扩展SQL注入器。

二、内置扩展SQL注入器有哪些?

1、自带扩展SQL注入器

Mybatis-Plus 扩展SQL注入器在扩展包下,为我们提供了可扩展的可注入方法:

Mybatis-Plus如何自定义SQL注入器?

AlwaysUpdateSomeColumnById : 根据id更新字段(全量更新不忽略null字段),updateById默认会自动忽略实体中null值字段。

InsertBatchSomeColumn : 真实批量插入,saveBatch其实是伪批量插入。

LogicDeleteBatchByIds : 逻辑删除增加填充功能,比如删除的时候填充更新时间、更新人。

Upsert : 插入一条数据(选择字段插入)。

2、SQL注入器全局配置

@Component public class MySqlInjector extends DefaultSqlInjector {          @Override     public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {         List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);         /**          * 把两个扩展内置扩展SQL注入器注入          */         methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));         methodList.add(new AlwaysUpdateSomeColumnById(i -> i.getFieldFill() != FieldFill.INSERT));         return methodList;     } } 

3、自定义Mapper

public interface MyBaseMapper<T> extends BaseMapper<T> {          /**      * 全字段更新,不会忽略null值      *      * @param entity 实体对象      */     int alwaysUpdateSomeColumnById(T entity);      /**      * 全量插入,等价于insert      *       * @param entityList 实体集合      */     int insertBatchSomeColumn(List<T> entityList); } 

三、扩展SQL注入器示例测试

1、用户表

CREATE TABLE `user` (   `id` int unsigned  AUTO_INCREMENT COMMENT '主键',   `username` varchar(128)  COMMENT '用户名',   `phone` varchar(32)  COMMENT '手机号',   `sex` char(1)  COMMENT '性别',   `create_time` datetime  COMMENT '创建时间',   `update_time` datetime  COMMENT '更新时间',   `deleted` tinyint DEFAULT '0' COMMENT '1、删除 0、未删除',   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1  

2、创建对应实体

@Data @Accessors(chain = true) @TableName("user") public class UserDO implements Serializable {      private static final long serialVersionUID = 1L;      @TableId(value = "id", type = IdType.AUTO)     private Integer id;      /**      * 用户名      */     @TableField("username")     private String username;      /**      * 手机号      */     @TableField("phone")     private String phone;      /**      * 性别      */     @TableField("sex")     private String sex;      /**      * 创建时间      */     @TableField(value = "create_time",fill = FieldFill.INSERT)     private LocalDateTime createTime;      /**      * 更新时间      */     @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)     private LocalDateTime updateTime;      /**      * 1、删除 0、未删除      */     @TableField(value = "deleted",fill = FieldFill.INSERT)     private Integer deleted; } 

其它有关代码这里就不粘贴了,具体看项目源码。

我们自定义的Mapper不再继承BaseMapper而是继承MyBaseMapper

 /**   *  通用mapper接口,以后创建其他mapper接口时,不再继承BaseMapper,而是继承MyBaseMapper   */ @Mapper public interface UserMapper extends MyBaseMapper<UserDO> {  } 

3、测试代码

@SpringBootTest @RunWith(SpringRunner.class) @ComponentScan("com.jincou.mybatisplus.dao") public class SqlInjectorTest  {     @Autowired    private UserMapper mapper;         @Test     public void alwaysUpdateSomeColumnById() {         UserDO user = new UserDO();         user.setUsername("小小");         user.setPhone(null);         user.setSex("女");         user.setId(1);         mapper.alwaysUpdateSomeColumnById(user);     }          @Test     public void insertBatchSomeColumn() {         UserDO user = new UserDO();         user.setUsername("zhangsan");         user.setPhone("13811111111");         user.setSex("女");          UserDO user1 = new UserDO();         user1.setUsername("lisi");         user1.setPhone("13822222222");         user1.setSex("男");          ArrayList<UserDO> userDOS = Lists.newArrayList(user, user1);         mapper.insertBatchSomeColumn(userDOS);     } } 

运行结果

alwaysUpdateSomeColumnById方法

Mybatis-Plus如何自定义SQL注入器?

insertBatchSomeColumn方法

Mybatis-Plus如何自定义SQL注入器?

成功!

四、如何自定义SQL注入器?

在实际开发过程中,当Mybatis-Plus自带的一些SQL注入器不满足我们的条件时,我们就需要自定义SQL注入器,整个流程也非常简单

这里我们以一个很简单的findAll方法为例进行学习。

在MyBaseMapper中添加findAll方法

public interface MyBaseMapper<T> extends BaseMapper<T> {        /**        *  查询所有用户        */       List<T> findAll(); } 

2、编写FindAll SQL注入器

public class FindAll extends AbstractMethod {      public FindAll() {         super("findAll");     }       public FindAll(String methodName) {         super(methodName);     }      @Override     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {         /* 执行 SQL ,动态 SQL 参考类 SqlMethod */         String sql = "select *  from " + tableInfo.getTableName();         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);         return this.addSelectMappedStatementForTable(mapperClass, sqlSource, tableInfo);     } } 

3、注册到Spring容器

@Component public class MySqlInjector extends DefaultSqlInjector {      @Override     public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {         List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);         /**          * 自定义SQL注入器注入          */         methodList.add(new FindAll());         return methodList;     } } 

4、测试

 @Test     public void findAll() {          List<UserDO> userDOS = mapper.findAll();     } 

Mybatis-Plus如何自定义SQL注入器?

成功!

补充

项目地址: https://github.com/yudiandemingzi/spring-boot-study

Mybatis-Plus官方SQL注入器示例地址:https://baomidou.com/pages/42ea4a/

声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!

发表评论

评论已关闭。

相关文章