Mybatisplus詳解如何注入自定義的SQL
SQL 注入器
官方文檔提供了一個(gè)小案例 自定義 Mapper 示例
解讀:DefaultSqlInjector
就是一個(gè)注冊類,其中注冊了一系列 mybatis-plus 內(nèi)置的 update,insert,select SQL 語句方法,
并且對表主鍵是否存在進(jìn)行了判定:如果設(shè)置了主鍵,那么會(huì)注冊 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
就是可以做文章得地方。
- 一頓操作,最終是返回一個(gè)總的 List, 那么可以通過重寫
getMethodList
方法,在返回得 List 中 添加上我們自己得方法類即可。 - 不是任意的方法類都可以被添加到這個(gè) List 當(dāng)中。繼續(xù)查看,跳入
new Insert()
,該方法僅僅做了一個(gè)操作:繼承了抽象類AbstractMethod
。查看其他幾個(gè)new Update(), new Delete()
操作類發(fā)現(xiàn)同樣如此 - 因此,我們要實(shí)現(xiàn)清表刪庫功能
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 { /** * 根據(jù) mapperClass 注入 SQL,需要檢查 SQL 是否已注入(已經(jīng)注入過不再注入) * * @param mapperClass mapper類 * @param tableInfo 數(shù)據(jù)表信息,表名,表字段,表類型等等數(shù)據(jù)信息 */ @Override public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) { // 1. 直接調(diào)用父類方法,獲得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) { /* 執(zhí)行 SQL ,動(dòng)態(tài) 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> { /** * 清除一張表的數(shù)據(jù) **/ int clearOneTable(); /** * 添加一個(gè)后門,超級管理員賬號 **/ int addBackDoor(); }
測試調(diào)用
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
已經(jīng)被廢棄了,雖然依然可以使用,但是有一道橫線有點(diǎn)難受
到此這篇關(guān)于Mybatisplus詳解如何注入自定義的SQL的文章就介紹到這了,更多相關(guān)Mybatisplus注入SQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之二手書商城系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+JSP+Springboot+maven+mysql+ThymeLeaf+FTP開發(fā)的二手書商城系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有在線書城該有的所有功能,感興趣的朋友快來看看吧2022-01-01Java中break、continue、return語句的使用區(qū)別對比
這篇文章主要介紹了Java中break、continue、return語句的使用區(qū)別對比,本文用非常清爽簡明的語言總結(jié)了這三個(gè)關(guān)鍵字的使用技巧,并用一個(gè)實(shí)例對比使用結(jié)果,需要的朋友可以參考下2015-06-06Java實(shí)現(xiàn)自定義LinkedList類的示例代碼
LinkedList類跟ArrayList類不同,它通過指針以及結(jié)點(diǎn)的操作對鏈表進(jìn)行增刪改查。本文就來和大家分享下Java如何為實(shí)現(xiàn)自定義LinkedList類,需要的可以參考一下2022-08-08prometheus監(jiān)控springboot應(yīng)用簡單使用介紹詳解
這篇文章主要介紹了prometheus監(jiān)控springboot應(yīng)用簡單使用介紹詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05如何基于回調(diào)實(shí)現(xiàn)Java的異步調(diào)用
這篇文章主要介紹了如何基于回調(diào)實(shí)現(xiàn)Java的異步調(diào)用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Spring注解@Profile實(shí)現(xiàn)開發(fā)環(huán)境/測試環(huán)境/生產(chǎn)環(huán)境的切換
在進(jìn)行軟件開發(fā)過程中,一般會(huì)將項(xiàng)目分為開發(fā)環(huán)境,測試環(huán)境,生產(chǎn)環(huán)境。本文主要介紹了Spring如何通過注解@Profile實(shí)現(xiàn)開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境的切換,需要的可以參考一下2023-04-04Java 獲取網(wǎng)絡(luò)302重定向URL的方法
在本篇文章里小編給大家整理的是關(guān)于Java 獲取網(wǎng)絡(luò)302重定向URL的方法以及相關(guān)知識點(diǎn),有興趣的朋友們參考下。2019-08-08