亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

大白話講解Mybatis的plugin(Interceptor)的使用

laznrbfe / 4335人閱讀

摘要:提供了一個(gè)入口,可以讓你在語(yǔ)句執(zhí)行過(guò)程中的某一點(diǎn)進(jìn)行攔截調(diào)用。

? ? ? ? mybatis提供了一個(gè)入口,可以讓你在語(yǔ)句執(zhí)行過(guò)程中的某一點(diǎn)進(jìn)行攔截調(diào)用。官方稱之為插件plugin,但是在使用的時(shí)候需要實(shí)現(xiàn)Interceptor接口,默認(rèn)情況下,MyBatis 允許使用插件來(lái)攔截的方法調(diào)用包括以下四個(gè)對(duì)象的方法:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

以上內(nèi)容在官網(wǎng)包括網(wǎng)上一搜一大把,但是用的時(shí)候,應(yīng)該怎么選擇,什么時(shí)候用哪種,怎么入手呢?

? ? ? ? 我一開(kāi)始想用的時(shí)候,也不知道什么時(shí)候攔截哪種對(duì)象,后來(lái)我就寫(xiě)了一個(gè)簡(jiǎn)單的demo,大家在用mybatis的時(shí)候,無(wú)非就是crud操作,那么我就提供四個(gè)plugin,分別來(lái)攔截Executor、ParameterHandler、ResultSetHandler、StatementHandler ;然后提供了一個(gè)controller暴露了五個(gè)接口分別是getUserInfo、listUserInfo、addUser、updateUser、deleteUser,來(lái)看下都走了那幾個(gè)plugin(demo我會(huì)上傳到碼云上,項(xiàng)目架構(gòu)是springboot+mybatis+mybatis-plus,數(shù)據(jù)庫(kù)我用的是postgresql-14),我認(rèn)為這五個(gè)接口涵蓋了我們?cè)陂_(kāi)發(fā)中90%的場(chǎng)景,根據(jù)打印的日志得到的結(jié)論是:

  1. 兩種查詢、新增、修改、刪除五個(gè)方法都會(huì)經(jīng)過(guò)StatementHandler、ParameterHandler
  2. 兩種查詢(單個(gè)查詢、列表查詢)都會(huì)經(jīng)過(guò)Executor、StatementHandler、ParameterHandler、ResultSetHandler

所以根據(jù)上面的結(jié)論,我們就可以來(lái)確定我們?cè)陂_(kāi)發(fā)中用哪種plugin,參考場(chǎng)景如下:

  1. 如果想改入?yún)?,比如postgresql據(jù)庫(kù)字段值大小寫(xiě)敏感,那么我可以在ParameterHandler里面獲取到入?yún)ⅲ缓髏oUpperCase();
  2. 如果想改sql語(yǔ)句,比如改postgresql的schema,那么我可以在StatementHandler(prepare)里面獲取到connection修改;若是查詢場(chǎng)景也可以在Executor的query方法中獲取connection修改;
  3. 如果想對(duì)數(shù)據(jù)進(jìn)行脫敏處理,比如查詢場(chǎng)景下的,查出的結(jié)果中身份證顯示前4位后4位中間***填充,那么我們可以在ResultSetHandler的進(jìn)行脫敏處理。

下面結(jié)合代碼舉兩個(gè)場(chǎng)景的例子:

場(chǎng)景一:對(duì)查詢結(jié)果數(shù)據(jù)脫敏處理,首先定義了一個(gè)XfactorResultSetHandlerInterceptor,代碼如下:

package com.lhclab.xfactor.dal.wrapper;import java.lang.reflect.Field;import java.sql.Statement;import java.util.List;import org.apache.commons.codec.binary.StringUtils;import org.apache.ibatis.executor.resultset.ResultSetHandler;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.SystemMetaObject;import lombok.extern.slf4j.Slf4j;@Slf4j@Intercepts({    @Signature(type= ResultSetHandler.class,method = "handleResultSets",args = {Statement.class})    })public class XfactorResultSetHandlerInterceptor implements Interceptor {    @Override    public Object intercept(Invocation invocation) throws Throwable {        log.info("===ResultSetHandler===");        Object resultSet = invocation.proceed();        List resultList = (List)resultSet;        for(Object item : resultList) {            Class sourceClass = item.getClass();            MetaObject metaObject = SystemMetaObject.forObject(item);            Field[] fields = sourceClass.getDeclaredFields();            for(Field field : fields) {                if(StringUtils.equals(field.getName(), "password")) {                    metaObject.setValue(field.getName(), "******");                }            }        }                return resultSet;    }}

plugin定義好以后,要想讓插件起作用,需要把插件加入到MybatisSqlSessionFactoryBean中,代碼如下(見(jiàn)標(biāo)黃的部分)

package com.lhclab.xfactor.dal.config;import javax.sql.DataSource;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;import org.springframework.boot.jdbc.DataSourceBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;import com.lhclab.xfactor.common.exception.XfactorRuntimeException;import com.lhclab.xfactor.dal.wrapper.XfactorExecutorInterceptor;import com.lhclab.xfactor.dal.wrapper.XfactorParameterHandlerInterceptor;import com.lhclab.xfactor.dal.wrapper.XfactorResultSetHandlerInterceptor;import com.lhclab.xfactor.dal.wrapper.XfactorStatementHandlerInterceptor;import com.zaxxer.hikari.HikariDataSource;import lombok.extern.slf4j.Slf4j;@Slf4j@Configuration@MapperScan("com.lhclab.xfactor.dal.dao")public class DataSourceConfig {        @Autowired    private DataSourceProperties properties;        @Bean    public DataSource dataSource() {        log.info("數(shù)據(jù)庫(kù)連接池創(chuàng)建中......");        HikariDataSource dataSource = null;        try {            dataSource = DataSourceBuilder.create(properties.getClassLoader())                    .type(HikariDataSource.class)                    .driverClassName(properties.determineDriverClassName())                    .url(properties.determineUrl())                    .username(properties.determineUsername()).password(properties.getPassword())                    .build();        } catch (Exception e) {            throw new XfactorRuntimeException("get password failed!", e);        }        return dataSource;    }        @Bean    public SqlSessionFactory xfactorSqlSessionFactory() throws Exception {        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();        sqlSessionFactoryBean.setDataSource(dataSource());//        sqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor(), new AnalyseMybatisPluginsInterceptor());        sqlSessionFactoryBean.setPlugins(new XfactorResultSetHandlerInterceptor(),                 new XfactorParameterHandlerInterceptor(),                 new XfactorStatementHandlerInterceptor(),                new XfactorExecutorInterceptor());        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();        sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/*xml"));        sqlSessionFactoryBean.setTypeAliasesPackage("com.lhclab.xfactor.dal.dao.entity");        return sqlSessionFactoryBean.getObject();    }        @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor() {        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));        return interceptor;    }}

場(chǎng)景二:更改查詢庫(kù)表的schema(場(chǎng)景類似于修改sql語(yǔ)句),首先定義了一個(gè)XfactorStatementHandlerInterceptor,代碼如下:

package com.lhclab.xfactor.dal.wrapper;import java.sql.Connection;import org.apache.ibatis.executor.statement.RoutingStatementHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.SystemMetaObject;import com.zaxxer.hikari.pool.HikariProxyConnection;import lombok.extern.slf4j.Slf4j;@Slf4j@Intercepts({    @Signature(type= StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),})public class XfactorStatementHandlerInterceptor implements Interceptor {    @Override    public Object intercept(Invocation invocation) throws Throwable {        log.info("===StatementHandler===");        ((HikariProxyConnection)invocation.getArgs()[0]).setSchema("notes");//這里改schema                //這里改sql,但是如果是對(duì)select的sql語(yǔ)句進(jìn)行修改,建議實(shí)現(xiàn)Executor.class的plugin中進(jìn)行,當(dāng)前方式改select語(yǔ)句insert/update/delete都會(huì)走這個(gè)判斷        MetaObject metaObject = SystemMetaObject.forObject(((RoutingStatementHandler)invocation.getTarget()).getBoundSql());        String execSql = (String) metaObject.getValue("sql");        if(execSql.startsWith("select ") || execSql.startsWith("SELECT ")) {            metaObject.setValue("sql", execSql.concat(" order by id desc"));        }        return invocation.proceed();    }}

結(jié)合以上兩個(gè)場(chǎng)景可知,有些目的可以通過(guò)多個(gè)類型的plugin都能實(shí)現(xiàn),但是肯定有一個(gè)是最佳方案的(plugin定義好以后,要想讓插件起作用,需要把插件加入到MybatisSqlSessionFactoryBean中,代碼見(jiàn)加粗的部分)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/123645.html

相關(guān)文章

  • 【深入淺出MyBatis筆記】插件

    摘要:插件插件接口在中使用插件,我們必須實(shí)現(xiàn)接口。它將直接覆蓋你所攔截對(duì)象原有的方法,因此它是插件的核心方法。插件在對(duì)象中的保存插件的代理和反射設(shè)計(jì)插件用的是責(zé)任鏈模式,的責(zé)任鏈?zhǔn)怯扇ザx的。 插件 1、插件接口 在MyBatis中使用插件,我們必須實(shí)現(xiàn)接口Interceptor。 public interface Interceptor { // 它將直接覆蓋你所攔截對(duì)象原有的方法,因...

    leon 評(píng)論0 收藏0
  • Mybatis Interceptor 攔截器

    摘要:攔截器的使用場(chǎng)景主要是更新數(shù)據(jù)庫(kù)的通用字段,分庫(kù)分表,加解密等的處理。攔截器均需要實(shí)現(xiàn)該接口。攔截器攔截器的使用需要查看每一個(gè)所提供的方法參數(shù)。對(duì)應(yīng)構(gòu)造器,為,為,為??蓞⒖紨r截器原理探究。 攔截器(Interceptor)在 Mybatis 中被當(dāng)做插件(plugin)對(duì)待,官方文檔提供了 Executor(攔截執(zhí)行器的方法),ParameterHandler(攔截參數(shù)的處理),Re...

    nemo 評(píng)論0 收藏0
  • 關(guān)于Mybatis攔截器對(duì)結(jié)果集攔截

    摘要:剛學(xué)習(xí)攔截器方面,在網(wǎng)上找了很多關(guān)于攔截器方面的文章,自己也嘗試過(guò)寫(xiě)過(guò)幾個(gè),但是關(guān)于結(jié)果集的攔截始終沒(méi)有找到合適的不要噴我,畢竟是新手。 剛學(xué)習(xí)Mybatis攔截器方面,在網(wǎng)上找了很多關(guān)于Mybatis攔截器方面的文章,自己也嘗試過(guò)寫(xiě)過(guò)幾個(gè),但是關(guān)于結(jié)果集的攔截始終沒(méi)有找到合適的(PS: 不要噴我,畢竟是新手)。也在segmentfault 上提問(wèn)過(guò),依然沒(méi)有找到一個(gè)易于理解的,后來(lái)自...

    kohoh_ 評(píng)論0 收藏0
  • Spring-Mybatis運(yùn)行機(jī)制概括

    摘要:使用這個(gè)類庫(kù)中的類將會(huì)加載必要的工廠類和類。最終它并不會(huì)依賴于或來(lái)構(gòu)建應(yīng)用程序代碼。下面對(duì)各部分作用總結(jié)下。和無(wú)縫整合的機(jī)制和的認(rèn)識(shí)在講如何無(wú)縫整合進(jìn)之前,我們先認(rèn)識(shí)下和這兩個(gè)接口的作用。附上上篇博文地址原理概括。 前言 本篇是繼上篇MyBatis原理概括延伸的,所以如果有小伙伴還沒(méi)看上篇博文的話,可以先去看下,也不會(huì)浪費(fèi)大家太多的時(shí)間,因?yàn)楸酒獣?huì)結(jié)合到上篇敘述的相關(guān)內(nèi)容。 好,切入正...

    qieangel2013 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<