Mybatis-Plus 自定义SQL注入器,非常实用!

一、什么是SQL注入器

我们在使用Mybatis-Plus时,dao层都会去继承BaseMapper接口,这样就可以用BaseMapper接口所有的方法,BaseMapper中每一个方法其实就是一个SQL注入器

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

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

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

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

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

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

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

1、自带扩展SQL注入器

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

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

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

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

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

2、SQL注入器全局配置

@Component
public class MySqlInjector extends DefaultSqlInjector {@Overridepublic List getMethodList(Class mapperClass, TableInfo tableInfo) {List 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 extends BaseMapper {/*** 全字段更新,不会忽略null值** @param entity 实体对象*/int alwaysUpdateSomeColumnById(@Param("et") T entity);/*** 全量插入,等价于insert* * @param entityList 实体集合*/int insertBatchSomeColumn(List 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 {}

3、测试代码

@SpringBootTest
@RunWith(SpringRunner.class)
@ComponentScan("com.jincou.mybatisplus.dao")
public class SqlInjectorTest  {@Autowiredprivate UserMapper mapper;@Testpublic void alwaysUpdateSomeColumnById() {UserDO user = new UserDO();user.setUsername("小小");user.setPhone(null);user.setSex("女");user.setId(1);mapper.alwaysUpdateSomeColumnById(user);}@Testpublic 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 userDOS = Lists.newArrayList(user, user1);mapper.insertBatchSomeColumn(userDOS);}
}

alwaysUpdateSomeColumnById方法运行结果

insertBatchSomeColumn方法运行结果

成功!

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

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

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

在MyBaseMapper中添加findAll方法

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

2、编写FindAll SQL注入器

public class FindAll extends AbstractMethod {public FindAll() {super("findAll");}public FindAll(String methodName) {super(methodName);}@Overridepublic 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 {@Overridepublic List getMethodList(Class mapperClass, TableInfo tableInfo) {List methodList = super.getMethodList(mapperClass, tableInfo);/*** 自定义SQL注入器注入*/methodList.add(new FindAll());return methodList;}
}

4、测试

 @Testpublic void findAll() {List userDOS = mapper.findAll();}

运行结果

成功!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部