有关Mybatis-Plus常用功能之前有做过一篇总结:
【资料图】
MyBatisPlus常用功能总结!(附项目示例)
一、什么是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
: 插入一条数据(选择字段插入)。
@Componentpublic class MySqlInjector extends DefaultSqlInjector { @Override public 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、自定义Mapperpublic interface MyBaseMapper extends BaseMapper { /** * 全字段更新,不会忽略null值 * * @param entity 实体对象 */ int alwaysUpdateSomeColumnById(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 */@Mapperpublic interface UserMapper extends MyBaseMapper {}
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 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); } @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容器@Componentpublic class MySqlInjector extends DefaultSqlInjector { @Override public List getMethodList(Class> mapperClass, TableInfo tableInfo) { List methodList = super.getMethodList(mapperClass, tableInfo); /** * 自定义SQL注入器注入 */ methodList.add(new FindAll()); return methodList; }}
4、测试@Test public void findAll() { List userDOS = mapper.findAll(); }
成功!
补充项目地址: https://github.com/yudiandemingzi/spring-boot-study
Mybatis-Plus官方SQL注入器示例地址:https://baomidou.com/pages/42ea4a/
声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!
标签: