spring?boot?Mybatis?攔截器實(shí)現(xiàn)拼接sql和修改的代碼詳解
定義一個(gè) SqlIntercepor 類
import com.culturalCenter.placeManage.globalConfig.Interface.InterceptAnnotation; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.DefaultReflectorFactory; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.session.ResultHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.sql.Statement; import java.util.Properties; @Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}), @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}), @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})}) @Component @Configuration public class SqlInterceptor implements Interceptor { private Logger logger = LoggerFactory.getLogger(SqlInterceptor.class); @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory()); //先攔截到RoutingStatementHandler,里面有個(gè)StatementHandler類型的delegate變量,其實(shí)現(xiàn)類是BaseStatementHandler,然后就到BaseStatementHandler的成員變量mappedStatement MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); //id為執(zhí)行的mapper方法的全路徑名,如com.uv.dao.UserMapper.insertUser String id = mappedStatement.getId(); logger.info("攔截到當(dāng)前請(qǐng)求方法的全路徑名為--->: " + id); //sql語(yǔ)句類型 select、delete、insert、update String sqlCommandType = mappedStatement.getSqlCommandType().toString(); BoundSql boundSql = statementHandler.getBoundSql(); //獲取到原始sql語(yǔ)句 String sql = boundSql.getSql(); String mSql = sql; //獲取參數(shù) Object parameter = statementHandler.getParameterHandler().getParameterObject(); logger.info("攔截到當(dāng)前請(qǐng)求SQL為--->: " + sql + "<------------>請(qǐng)求類型為: " + sqlCommandType); logger.info("攔截到當(dāng)前請(qǐng)求參數(shù)為--->: " + parameter); //TODO 修改位置 //注解邏輯判斷 添加注解了才攔截//InterceptAnnotation Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf("."))); String mName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length()); for (Method method : classType.getDeclaredMethods()) { if (method.isAnnotationPresent(InterceptAnnotation.class) && mName.equals(method.getName())) { InterceptAnnotation interceptorAnnotation = method.getAnnotation(InterceptAnnotation.class); if (interceptorAnnotation.flag()) { mSql = sql + " limit 2"; } } } //通過(guò)反射修改sql語(yǔ)句 Field field = boundSql.getClass().getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, mSql); return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, new SqlInterceptor()); } @Override public void setProperties(Properties properties) { // this.setProperties(properties); }
自定義一個(gè)注解類實(shí)現(xiàn)局部處理SQL修改
InterceptAnnotation
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 配合SqlInterceptor實(shí)現(xiàn)局部攔截 * */ @Target({ElementType.METHOD,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface InterceptAnnotation { boolean flag() default true; }
自定義數(shù)據(jù)源工廠類
SqlSessionFactoryConfig
package com.culturalCenter.placeManage.globalConfig; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.sql.DataSource; /** * @author wulincheng * @Date 2020年6月23日18:25:22 * 創(chuàng)建SQL連接工廠類 * */ @Configuration public class SqlSessionFactoryConfig { @javax.annotation.Resource DruidDataSource dataSource; /** * @Autowired SqlSessionFactory sqlSessionFactory; * SqlSession session = sqlSessionFactory.openSession(); * //創(chuàng)建sqlMapper * SqlMapper sqlMapper = new SqlMapper(session); */ @Bean @Primary public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource);//更多參數(shù)請(qǐng)自行注入 bean.setPlugins(new Interceptor[]{new SqlInterceptor()}); Resource[] resources = new PathMatchingResourcePatternResolver() .getResources("classpath*:mapper/*.xml"); bean.setMapperLocations(resources); return bean.getObject(); } }
到此這篇關(guān)于spring boot Mybatis 攔截器,實(shí)現(xiàn)拼接sql和修改的文章就介紹到這了,更多相關(guān)spring boot Mybatis 攔截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MybatisPlusInterceptor實(shí)現(xiàn)sql攔截器超詳細(xì)教程
- Mybatis之如何攔截慢SQL日志記錄
- Mybatis-Plus實(shí)現(xiàn)SQL攔截器的示例
- 利用Mybatis?Plus實(shí)現(xiàn)一個(gè)SQL攔截器
- Mybatis攔截器打印sql問(wèn)題
- MyBatis如何通過(guò)攔截修改SQL
- MyBatis自定義SQL攔截器示例詳解
- mybatis 通過(guò)攔截器打印完整的sql語(yǔ)句以及執(zhí)行結(jié)果操作
- mybatis 實(shí)現(xiàn) SQL 查詢攔截修改詳解
- MyBatis的動(dòng)態(tài)攔截sql并修改
相關(guān)文章
Java實(shí)現(xiàn)月餅的制作、下單和售賣(mài)功能
這篇文章主要介紹了Java實(shí)現(xiàn)月餅的制作、下單和售賣(mài),借此機(jī)會(huì),我們用Lambda實(shí)現(xiàn)一遍月餅制作,下單,售賣(mài)的開(kāi)發(fā)設(shè)計(jì)模式,主要有制作月餅的工廠模式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Java實(shí)現(xiàn)分庫(kù)分表實(shí)踐指南
在開(kāi)發(fā)中我們經(jīng)常使用到分庫(kù)分表,但是一般是我們前期就已經(jīng)做了規(guī)劃,對(duì)數(shù)據(jù)庫(kù)怎么劃分,對(duì)哪些表進(jìn)行分表,這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)分庫(kù)分表的相關(guān)資料,需要的朋友可以參考下2024-01-01Spring Cloud Data Flow初體驗(yàn)以Local模式運(yùn)行
這篇文章主要介紹了Spring Cloud Data Flow初體驗(yàn)以Local模式運(yùn)行,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08springboot之端口設(shè)置和contextpath的配置方式
這篇文章主要介紹了springboot之端口設(shè)置和contextpath的配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01使用Mybatis-plus實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)表的內(nèi)部字段進(jìn)行比較
這篇文章主要介紹了使用Mybatis-plus實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)表的內(nèi)部字段進(jìn)行比較方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07Spring Boot Rest控制器單元測(cè)試過(guò)程解析
這篇文章主要介紹了Spring Boot Rest控制器單元測(cè)試過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Java實(shí)現(xiàn)統(tǒng)計(jì)字符串出現(xiàn)的次數(shù)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)統(tǒng)計(jì)字符串出現(xiàn)的次數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10深入淺出講解Spring框架中依賴注入與控制反轉(zhuǎn)及應(yīng)用
依賴注入(Dependency?Injection)和控制反轉(zhuǎn)(Inversion?of?Control)是同一個(gè)概念。具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí),在?傳統(tǒng)的程序設(shè)計(jì)過(guò)程中,通常由調(diào)用者來(lái)創(chuàng)建被調(diào)用者的實(shí)例2022-03-03