mybatis-plus提供了许多默认单表CRUD语句,对于其他SQL情况爱莫能助。如果有一个删库跑路,并且需要多次调用,来清空多张表数据得需求,那么如何把他封装在mybatis-plus中调用呢,下面我们一起来看一下
SQL 注入器
官方文档提供了一个小案例 自定义 Mapper 示例
解读:DefaultSqlInjector
就是一个注册类,其中注册了一系列 mybatis-plus 内置的 update,insert,select SQL 语句方法,
并且对表主键是否存在进行了判定:如果设置了主键,那么会注册 DeleteById 等方法,没有则不注册。最终返回所有将要被注入的 SQL 语句 List
public class DefaultSqlInjector extends AbstractSqlInjector {
public DefaultSqlInjector() {}
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
Builder<AbstractMethod> builder = Stream.builder().add(new Insert()).add(new Delete()).add(new DeleteByMap()).add(new Update()).add(new SelectByMap()).add(new SelectCount()).add(new SelectMaps()).add(new SelectMapsPage()).add(new SelectObjs()).add(new SelectList()).add(new SelectPage());
if (tableInfo.havePK()) {
builder.add(new DeleteById()).add(new DeleteBatchByIds()).add(new UpdateById()).add(new SelectById()).add(new SelectBatchByIds());
} else {
this.logger.warn(String.format("%s ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.", tableInfo.getEntityType()));
}
return (List)builder.build().collect(Collectors.toList());
}
}
其中,Builder<AbstractMethod> builder
就是可以做文章得地方。
- 一顿操作,最终是返回一个总的 List, 那么可以通过重写
getMethodList
方法,在返回得 List 中 添加上我们自己得方法类即可。 - 不是任意的方法类都可以被添加到这个 List 当中。继续查看,跳入
new Insert()
,该方法仅仅做了一个操作:继承了抽象类AbstractMethod
。查看其他几个new Update(), new Delete()
操作类发现同样如此 - 因此,我们要实现清表删库功能
clearOneTable
, 同样只需要继承抽象类AbstractMethod
完事。
第一步重写getMethodList
RegisterSqlInjector.java
package com.example.commonmybatisplus.utils;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Collections;
import java.util.List;
/**
* @Author ifredomvip@gmail.com
* @Date 2022/5/30 11:11
* @Version 1.0.0
* @Description
* 源码阅读: https://sourcegraph.com/github.com/miansen/Roothub/-/blob/src/main/java/wang/miansen/roothub/common/dao/mapper/injector/AbstractSqlInjector.java?L56
**/
// 基于springboot的注解: @Component
@Component
public class RegisterSqlInjector extends DefaultSqlInjector {
/**
* 根据 mapperClass 注入 SQL,需要检查 SQL 是否已注入(已经注入过不再注入)
*
* @param mapperClass mapper类
* @param tableInfo 数据表信息,表名,表字段,表类型等等数据信息
*/
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
// 1. 直接调用父类方法,获得mybatis-plus注入SQL方法后的List
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
methodList.forEach(System.out::println);
// 2. 添加我自定义得类
methodList.add(new DefineSqlInjector());
return methodList;
}
}
第二步定义自己的SQL方法类
DefineSqlInjector.java
package com.example.commonmybatisplus.utils;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
import com.baomidou.mybatisplus.core.injector.methods.*;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Author ifredomvip@gmail.com
* @Date 2022/5/30 11:12
* @Version 1.0.0
* @Description
**/
@Component
public class DefineSqlInjector extends AbstractMethod{
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
/* 执行 SQL ,动态 SQL 参考类 SqlMethod */
String sql = "delete from " + tableInfo.getTableName();
/* mapper 接口方法名一致 */
String method = "clearOneTable";
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
}
}
第三步定义添加了自定义方法的Mapper类
package com.example.commonmybatisplus.utils;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.commonmybatisplus.entity.UserEntity;
/**
* @Author ifredomvip@gmail.com
* @Date 2022/5/30 8:55
* @Version 1.0.0
* @Description
**/
public interface BaseDao<T> extends BaseMapper<T> {
/**
* 清除一张表的数据
**/
int clearOneTable();
/**
* 添加一个后门,超级管理员账号
**/
int addBackDoor();
}
测试调用
package com.example.commonmybatisplus;
import com.example.commonmybatisplus.dao.UserDao;
import com.example.commonmybatisplus.entity.UserEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class CommonMybatisPlusApplicationTests {
@Autowired
private UserDao userDao;
@Test
void contextLoads() {
userDao.clearOneTable();
}
}
遗留问题
目前最新的 mysql-plus 版本提示 AbstractMethod
已经被废弃了,虽然依然可以使用,但是有一道横线有点难受
到此这篇关于Mybatisplus详解如何注入自定义的SQL的文章就介绍到这了,更多相关Mybatisplus注入SQL内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
本文标题为:Mybatisplus详解如何注入自定义的SQL
基础教程推荐
- ConditionalOnProperty配置swagger不生效问题及解决 2023-01-02
- Java实现线程插队的示例代码 2022-09-03
- Java实现查找文件和替换文件内容 2023-04-06
- Java并发编程进阶之线程控制篇 2023-03-07
- java基础知识之FileInputStream流的使用 2023-08-11
- Java文件管理操作的知识点整理 2023-05-19
- java实现多人聊天系统 2023-05-19
- Java数据结构之对象比较详解 2023-03-07
- JDK数组阻塞队列源码深入分析总结 2023-04-18
- springboot自定义starter方法及注解实例 2023-03-31