最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合Mybatis自定義攔截器不起作用的處理方案

 更新時(shí)間:2021年09月23日 12:05:31   作者:小胖學(xué)編程  
這篇文章主要介紹了SpringBoot整合Mybatis自定義攔截器不起作用的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

SpringBoot整合Mybatis自定義攔截器不起作用

Mybatis插件生效的方式:

1. 原始的讀取mybatis-config.xml文件

該方式和Spring無(wú)關(guān),是通過(guò)反射的形式創(chuàng)建插件對(duì)象,此時(shí)會(huì)執(zhí)行org.apache.ibatis.plugin.Interceptor#setProperties方法,以讀取配置參數(shù)。

mybatis:
  mapper-locations: classpath*:/mapping/*.xml
  type-aliases-package: com.tellme.pojo
  #讀取全局配置的地址
  config-location: classpath:mybatis-config.xml

在resource目錄下配置mybatis的全局配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="multipleResultSetsEnabled" value="true"/>
        <setting name="useColumnLabel" value="true"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="useGeneratedKeys" value="true"/>
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <setting name="defaultStatementTimeout" value="25000"/>
    </settings>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer"/>
        <typeAlias alias="Long" type="java.lang.Long"/>
        <typeAlias alias="HashMap" type="java.util.HashMap"/>
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
        <typeAlias alias="ArrayList" type="java.util.ArrayList"/>
        <typeAlias alias="LinkedList" type="java.util.LinkedList"/>
    </typeAliases>
    <!--配置的插件名-->
    <plugins>
        <plugin interceptor="com.xxx.yyy.plugins.PrintSqlInfoInterceptor"/>
    </plugins>
</configuration>

2. 與SpringBoot容器整合

網(wǎng)上很多方案說(shuō):mybatis自定義攔截器上加上@Component注解便可以生效。但是我將自定義攔截器放入到Spring容器中,自定義攔截器卻失效了。

然后找到了springboot配置多數(shù)據(jù)源后mybatis攔截器失效文章,說(shuō)是自定義配置了數(shù)據(jù)源導(dǎo)致了攔截器失效。

2.1 mybatis的自動(dòng)裝載

源碼位置:org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

@Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {
  private static Log log = LogFactory.getLog(MybatisAutoConfiguration.class);
  @Autowired
  private MybatisProperties properties;
   //會(huì)依賴(lài)注入Spring容器中所有的mybatis的Interceptor攔截器
  @Autowired(required = false)
  private Interceptor[] interceptors;
   ...
  @Bean
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setVfs(SpringBootVFS.class);
    if (StringUtils.hasText(this.properties.getConfigLocation())) {
      factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
    factory.setConfiguration(properties.getConfiguration());
    //手動(dòng)放入到了setPlugins方法中。
    if (!ObjectUtils.isEmpty(this.interceptors)) {
      factory.setPlugins(this.interceptors);
    }
    if (this.databaseIdProvider != null) {
      factory.setDatabaseIdProvider(this.databaseIdProvider);
    }
    if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
      factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
    }
    if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
      factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
    }
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
      factory.setMapperLocations(this.properties.resolveMapperLocations());
    }
    return factory.getObject();
  }
   ...
}

上面源碼中:自動(dòng)注入了Interceptor[]數(shù)組(我們只需將mybatis的自定義攔截器對(duì)象放入到Spring容器中)。后續(xù)放入了sqlSessionFactory中。

但是項(xiàng)目中雖然自定義配置了sqlSessionFactory類(lèi),但卻未設(shè)置factory.setPlugins(this.interceptors);。導(dǎo)致即使將自定義攔截器放入到Spring容器,但卻不生效。

解決方法,需要手動(dòng)修改自定義的sqlSessionFactory類(lèi)。

3. 在mybatis-config.xml配置又放入Spring容器

這種情況下,mybatis自定義攔截器會(huì)被執(zhí)行兩次。即在mybatis-config.xml配置的攔截器會(huì)通過(guò)反射的方式創(chuàng)建攔截器,放入Spring容器的攔截器也會(huì)被初始化。

源碼位置:org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory

protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
    Configuration configuration;
    ...讀取屬性中的plugins,即org.mybatis.spring.SqlSessionFactoryBean#setPlugins設(shè)置的。
    if (!isEmpty(this.plugins)) {
        for (Interceptor plugin: this.plugins) {
            configuration.addInterceptor(plugin);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Registered plugin: '" + plugin + "'");
            }
        }
    }
    ...解析xml配置(通過(guò)反射創(chuàng)建攔截器對(duì)象)
    if (xmlConfigBuilder != null) {
        try {
            xmlConfigBuilder.parse();
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Parsed configuration file: '" + this.configLocation + "'");
            }
        } catch(Exception ex) {
            throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);
        } finally {
            ErrorContext.instance().reset();
        }
    }
    return this.sqlSessionFactoryBuilder.build(configuration);
}

最終會(huì)執(zhí)行到:

private void pluginElement(XNode parent) throws Exception {
    if (parent != null) {
        for (XNode child: parent.getChildren()) {
            String interceptor = child.getStringAttribute("interceptor");
            Properties properties = child.getChildrenAsProperties();
            //反射創(chuàng)建mybatis的插件。
            Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
            interceptorInstance.setProperties(properties);
            configuration.addInterceptor(interceptorInstance);
        }
    }
}

SpringBoot 自定義Mybatis攔截器

開(kāi)發(fā)過(guò)程中經(jīng)?;匦枰獙?duì)要執(zhí)行的sql加以自定義處理,比如分頁(yè),計(jì)數(shù)等。通過(guò) MyBatis 提供的強(qiáng)大機(jī)制,使用插件是非常簡(jiǎn)單的,只需實(shí)現(xiàn) Interceptor 接口,并指定想要攔截的方法簽名即可。

@Intercepts({@Signature(type = Executor.class,method = "query",args = {MappedStatement.class,Object.class, RowBounds.class,ResultHandler.class})})
public class MyPageInterceptor implements Interceptor {
    private static final Logger logger= LoggerFactory.getLogger(MyPageInterceptor.class);
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        logger.warn(invocation.toString());
        return invocation.proceed();
    }
    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o,this);
    }
    @Override
    public void setProperties(Properties properties) {
        logger.warn(properties.toString());
    }
}

我的配置

mybatis:
  type-aliases-package: me.zingon.pagehelper.model
  mapper-locations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true
    default-fetch-size: 100
    default-statement-timeout: 30

在springboot中要給mybatis加上這個(gè)攔截器,有三種方法,前兩種方法在啟動(dòng)項(xiàng)目時(shí)不會(huì)自動(dòng)調(diào)用自定義攔截器的setProperties方法。

第一種

直接給自定義攔截器添加一個(gè)@Component注解,當(dāng)調(diào)用sql時(shí)結(jié)果如下,可以看到攔截器生效了,但是啟動(dòng)時(shí)候并沒(méi)有自動(dòng)調(diào)用setProperties方法。

第二種

在配置類(lèi)里添加攔截器,這種方法結(jié)果同上,也不會(huì)自動(dòng)調(diào)用setProperties方法。

@Configuration
public class MybatisConfig {
    @Bean
    ConfigurationCustomizer mybatisConfigurationCustomizer() {
        return new ConfigurationCustomizer() {
            @Override
            public void customize(org.apache.ibatis.session.Configuration configuration) {
                configuration.addInterceptor(new MyPageInterceptor());
            }
        };
    }
}

第三種

這種方法就是跟以前的配置方法類(lèi)似,在yml配置文件中指定mybatis的xml配置文件,注意config-location屬性和configuration屬性不能同時(shí)指定

mybatis:
  config-location: classpath:mybatis.xml
  type-aliases-package: me.zingon.pagehelper.model
  mapper-locations: classpath:mapper/*.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="me.zingon.pacargle.model"/>
    </typeAliases>
    <plugins>
        <plugin interceptor="me.zingon.pagehelper.interceptor.MyPageInterceptor"> 
            <property name="dialect" value="oracle"/>
        </plugin>
    </plugins>
</configuration>

可以看到,在啟動(dòng)項(xiàng)目的時(shí)候setProperties被自動(dòng)調(diào)用了

前兩種方法可以在初始化自定義攔截器的時(shí)候通過(guò) @Value 注解直接初始化需要的參數(shù)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MyBatis實(shí)現(xiàn)三級(jí)樹(shù)查詢(xún)的示例代碼

    MyBatis實(shí)現(xiàn)三級(jí)樹(shù)查詢(xún)的示例代碼

    在實(shí)際項(xiàng)目開(kāi)發(fā)中,樹(shù)形結(jié)構(gòu)的數(shù)據(jù)查詢(xún)是一個(gè)非常常見(jiàn)的需求,比如組織架構(gòu)、菜單管理、地區(qū)選擇等場(chǎng)景都需要處理樹(shù)形數(shù)據(jù),本文將詳細(xì)講解如何使用MyBatis實(shí)現(xiàn)三級(jí)樹(shù)形數(shù)據(jù)的查詢(xún),需要的朋友可以參考下
    2024-12-12
  • drools中使用function的方法小結(jié)

    drools中使用function的方法小結(jié)

    當(dāng)我們?cè)赿rools中編寫(xiě)規(guī)則時(shí),有些時(shí)候存在重復(fù)的代碼,那么我們是否可以將這些重復(fù)代碼抽取出來(lái),封裝成一個(gè)function來(lái)調(diào)用呢?那么在drools中如何自定義function?下面小編給大家介紹下drools中使用function的方法,需要的朋友可以參考下
    2022-05-05
  • 帶你了解Java的類(lèi)和對(duì)象

    帶你了解Java的類(lèi)和對(duì)象

    下面小編就為大家?guī)?lái)一篇全面理解Java類(lèi)和對(duì)象。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-09-09
  • 解決try-catch捕獲異常信息后Spring事務(wù)失效的問(wèn)題

    解決try-catch捕獲異常信息后Spring事務(wù)失效的問(wèn)題

    這篇文章主要介紹了解決try-catch捕獲異常信息后Spring事務(wù)失效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JAVA實(shí)現(xiàn)Base64編碼的三種方式

    JAVA實(shí)現(xiàn)Base64編碼的三種方式

    本文主要介紹了JAVA實(shí)現(xiàn)Base64編碼的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • java實(shí)現(xiàn)多人多牌數(shù)比較游戲

    java實(shí)現(xiàn)多人多牌數(shù)比較游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多人多牌數(shù)比較游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • JavaWeb工程中集成YMP框架快速上手(二)

    JavaWeb工程中集成YMP框架快速上手(二)

    YMP是一個(gè)非常簡(jiǎn)單、易用的一套輕量級(jí)JAVA應(yīng)用開(kāi)發(fā)框架,設(shè)計(jì)原則主要側(cè)重于簡(jiǎn)化工作任務(wù)、規(guī)范開(kāi)發(fā)流程、提高開(kāi)發(fā)效率。對(duì)YMP框架感興趣的小伙伴們可以參考一下
    2016-02-02
  • SpringBoot啟動(dòng)多數(shù)據(jù)源找不到合適的驅(qū)動(dòng)類(lèi)問(wèn)題

    SpringBoot啟動(dòng)多數(shù)據(jù)源找不到合適的驅(qū)動(dòng)類(lèi)問(wèn)題

    這篇文章主要介紹了SpringBoot啟動(dòng)多數(shù)據(jù)源找不到合適的驅(qū)動(dòng)類(lèi)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java查看本機(jī)端口是否被占用源碼

    Java查看本機(jī)端口是否被占用源碼

    這篇文章主要介紹了Java查看本機(jī)端口是否被占用的主要原理,并結(jié)合具體實(shí)例給出了操作方法,需要的朋友可以參考下
    2017-09-09
  • web.xml中servlet, bean, filter, listenr 加載順序_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    web.xml中servlet, bean, filter, listenr 加載順序_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了web.xml中servlet, bean, filter, listenr 加載順序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評(píng)論

临高县| 凤凰县| 江山市| 郧西县| 栾川县| 临清市| 孟村| 临湘市| 白河县| 云安县| 兰西县| 资兴市| 志丹县| 南昌市| 景泰县| 茶陵县| 宁德市| 沙坪坝区| 铜山县| 获嘉县| 石首市| 左贡县| 青阳县| 保山市| 水富县| 龙州县| 罗田县| 桐庐县| 鄢陵县| 宝清县| 页游| 桓仁| 浠水县| 海阳市| 平陆县| 边坝县| 明水县| 无棣县| 舒兰市| 吴忠市| 宝应县|