有关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 : 插入一条数据(选择字段插入)。

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方法

insertBatchSomeColumn方法

成功!

四、如何自定义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();
}

成功!

补充

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

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

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

Mybatis-Plus如何自定义SQL注入器?的更多相关文章

  1. Mybatis之执行自定义SQL举例

    本文说明如何使用Mybatis执行我自定义输入的SQL语句. 需要的mybaits文件包括:配置文件(mybatis-config-dao.xml 和 jdbc.properties).接口文件(IS ...

  2. SpringBoot Mybatis 执行自定义SQL

    1.XML中执行自定义SQL. https://blog.csdn.net/u012427355/article/details/80654806 2.注解执行自定义SQL @Select(" ...

  3. mybatis对java自定义注解的使用——入门篇

    最近在学习spring和ibatis框架. 以前在天猫实习时做过的一个小项目用到的mybatis,在其使用过程中,不加思索的用了比较原始的一种持久化方式: 在一个包中写一个DAO的接口,在另一个包里面 ...

  4. Mybatis中常用的SQL

    1.BaseResultMap <resultMap id="BaseResultMap" type="com.stylefeng.guns.common.pers ...

  5. mybatis对java自定义注解的使用

    转自:https://www.cnblogs.com/sonofelice/p/4980161.html 最近在学习spring和ibatis框架. 以前在天猫实习时做过的一个小项目用到的mybati ...

  6. mybatis入门案例自定义实现

    mybatis入门案例自定义实现 一.需要实现的类和接口 public static void main(String[] args) throws Exception{ //1.读取配置文件 Inp ...

  7. Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!

    之前讲了Springboot整合Mybatis,介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.mybatis 插件自动生成的mappe ...

  8. 小书MybatisPlus第3篇-自定义SQL

    本文档为一个系列,前面章节: 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总结 书接上回,虽然Mybatis Plu ...

  9. mybatis-plus 自定义SQL,XML形式,传参的几种方式

    mybatis-plus 自定义SQL,XML形式,传参的几种方式 前提说明 所涉及文件 传参类型说明 1.Java代码中使用QueryWrapper动态拼装SQL 2.简单类型参数(如String, ...

  10. spring boot集成mybatis-plus插件进行自定义sql方法开发时报nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    spring boot集成mybatis-plus插件进行自定义sql方法开发时报nested exception is org.apache.ibatis.binding.BindingExcept ...

随机推荐

  1. 2019 CSP J/S第2轮 视频与题解

    CSP入门组和提高组第二轮题解 转自网络

  2. C输入输出

    由于刚开始学的是cin和cout进行输入和输出,好多时候就不会写printf和scanf,所以导致有时候程序运行超时也不会改正,所以今天先说一说scanf和printf. 这是cin和cout的格式: ...

  3. [读书笔记]FDTD与YEE晶胞

    截图选自Understanding the Finite-Difference Time-Domain Metho  作者是John B. Schneider 有限差分时域(FDTD)方法使用有限差分 ...

  4. Selenium显式、隐式等待

    显式等待: 显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码.简单的说就是在指定时间内,一直等待某个条件成立,条件成立后立即执行定位元素的操作:如果超过这个时间条件仍然没有成立,则会抛出 ...

  5. 重写antd组件样式

    :global { .ant-select-selection-placeholder { color: #FFF; font-size: 14px; } .ant-select-selection- ...

  6. Blog作业02

    目录 前言 设计与分析 踩坑心得 改进建议 总结 前言 这三次作业的题目数量虽然增多,但是在题量加大的同时,这三次作业集的难度也相应的下去了,难度降低的同时也保证了作业集题目的质量.这三次的作业的知识 ...

  7. [jointjs] 自定义shape

    前面一篇写了使用jointjs实现自动布局和拖拽缩放,这篇记录一下自定义图形. 首先jointjs内置的图形有很多,文档已经列出来了: 但是有时候这些图形满足不了我们的需求,就需要我们自己去绘制自己想 ...

  8. Cesium渲染模块之Shader

    1. 引言 Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业 ...

  9. Github学生认证具体步骤

    具体步骤展示 一.进入相关的申请地址 地址在此:https://education.github.com/pack/ 二.选中右上方的Student,然后选择第二个选项 在我们已经注册号Github账 ...

  10. 对于利用JavaBean+Servlet+jsp实现增删改查功能题目的实现

    首先,为了更好地规范代码,可以分别将不同用处的Java文件放置到不同的文件夹里面 对于实体类,可以放在名为Bean的package里面 对于中间用来实现Java与jsp页面交互的类,可以放在名为Ser ...