国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

laznrbfe / 4134人閱讀

摘要:提供了一個入口,可以讓你在語句執行過程中的某一點進行攔截調用。

? ? ? ? mybatis提供了一個入口,可以讓你在語句執行過程中的某一點進行攔截調用。官方稱之為插件plugin,但是在使用的時候需要實現Interceptor接口,默認情況下,MyBatis 允許使用插件來攔截的方法調用包括以下四個對象的方法:

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

以上內容在官網包括網上一搜一大把,但是用的時候,應該怎么選擇,什么時候用哪種,怎么入手呢?

? ? ? ? 我一開始想用的時候,也不知道什么時候攔截哪種對象,后來我就寫了一個簡單的demo,大家在用mybatis的時候,無非就是crud操作,那么我就提供四個plugin,分別來攔截Executor、ParameterHandler、ResultSetHandler、StatementHandler ;然后提供了一個controller暴露了五個接口分別是getUserInfo、listUserInfo、addUser、updateUser、deleteUser,來看下都走了那幾個plugin(demo我會上傳到碼云上,項目架構是springboot+mybatis+mybatis-plus,數據庫我用的是postgresql-14),我認為這五個接口涵蓋了我們在開發中90%的場景,根據打印的日志得到的結論是:

  1. 兩種查詢、新增、修改、刪除五個方法都會經過StatementHandler、ParameterHandler
  2. 兩種查詢(單個查詢、列表查詢)都會經過Executor、StatementHandler、ParameterHandler、ResultSetHandler

所以根據上面的結論,我們就可以來確定我們在開發中用哪種plugin,參考場景如下:

  1. 如果想改入參,比如postgresql據庫字段值大小寫敏感,那么我可以在ParameterHandler里面獲取到入參,然后toUpperCase();
  2. 如果想改sql語句,比如改postgresql的schema,那么我可以在StatementHandler(prepare)里面獲取到connection修改;若是查詢場景也可以在Executor的query方法中獲取connection修改;
  3. 如果想對數據進行脫敏處理,比如查詢場景下的,查出的結果中身份證顯示前4位后4位中間***填充,那么我們可以在ResultSetHandler的進行脫敏處理。

下面結合代碼舉兩個場景的例子:

場景一:對查詢結果數據脫敏處理,首先定義了一個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中,代碼如下(見標黃的部分)

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("數據庫連接池創建中......");        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;    }}

場景二:更改查詢庫表的schema(場景類似于修改sql語句),首先定義了一個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,但是如果是對select的sql語句進行修改,建議實現Executor.class的plugin中進行,當前方式改select語句insert/update/delete都會走這個判斷        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();    }}

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/123645.html

相關文章

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

    摘要:插件插件接口在中使用插件,我們必須實現接口。它將直接覆蓋你所攔截對象原有的方法,因此它是插件的核心方法。插件在對象中的保存插件的代理和反射設計插件用的是責任鏈模式,的責任鏈是由去定義的。 插件 1、插件接口 在MyBatis中使用插件,我們必須實現接口Interceptor。 public interface Interceptor { // 它將直接覆蓋你所攔截對象原有的方法,因...

    leon 評論0 收藏0
  • Mybatis Interceptor 攔截器

    摘要:攔截器的使用場景主要是更新數據庫的通用字段,分庫分表,加解密等的處理。攔截器均需要實現該接口。攔截器攔截器的使用需要查看每一個所提供的方法參數。對應構造器,為,為,為。可參考攔截器原理探究。 攔截器(Interceptor)在 Mybatis 中被當做插件(plugin)對待,官方文檔提供了 Executor(攔截執行器的方法),ParameterHandler(攔截參數的處理),Re...

    nemo 評論0 收藏0
  • 關于Mybatis攔截器對結果集攔截

    摘要:剛學習攔截器方面,在網上找了很多關于攔截器方面的文章,自己也嘗試過寫過幾個,但是關于結果集的攔截始終沒有找到合適的不要噴我,畢竟是新手。 剛學習Mybatis攔截器方面,在網上找了很多關于Mybatis攔截器方面的文章,自己也嘗試過寫過幾個,但是關于結果集的攔截始終沒有找到合適的(PS: 不要噴我,畢竟是新手)。也在segmentfault 上提問過,依然沒有找到一個易于理解的,后來自...

    kohoh_ 評論0 收藏0
  • Spring-Mybatis運行機制概括

    摘要:使用這個類庫中的類將會加載必要的工廠類和類。最終它并不會依賴于或來構建應用程序代碼。下面對各部分作用總結下。和無縫整合的機制和的認識在講如何無縫整合進之前,我們先認識下和這兩個接口的作用。附上上篇博文地址原理概括。 前言 本篇是繼上篇MyBatis原理概括延伸的,所以如果有小伙伴還沒看上篇博文的話,可以先去看下,也不會浪費大家太多的時間,因為本篇會結合到上篇敘述的相關內容。 好,切入正...

    qieangel2013 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<