springboot+mybatis拦截器不生效问题分析

Posted 阿毛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot+mybatis拦截器不生效问题分析相关的知识,希望对你有一定的参考价值。

一、环境信息
SpringBoot:2.3.6.RELEASE
Mybatis-plus:3.3.1
二、碰到问题
今天因业务系统功能需要,使用mybatis的拦截器对ORACLE的数据库会话进行用户当前语言环境设置(NLS_LANGUAGE),碰到拦截器代码不生效的问题,特此记录下来,方便将来查阅。
三、代码如下:
1、在Mybatis的@Configuration相关代码添加如下代码(自动注入到拦截器链):

/**
 * 更改会话状态
 *
 * @return
 */
@Bean
public AlterSessionInterceptor alterSessionInterceptor() {
    return new AlterSessionInterceptor();
}

2、拦截器代码(拦截StatementHandler的prepare方法,取到Connection执行ALTER SESSION的语句):
/**

  • <p>
  • 更改会话解析器
  • </p>
    *
  • @since 2021/7/14
    */

@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class AlterSessionInterceptor implements Interceptor {

@Override
public Object intercept(Invocation invocation) throws Throwable {
    Object[] args = invocation.getArgs();
    Connection connection = (Connection) args[0];
    if ("Oracle".equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) {
        Statement statement = null;
        try {
            statement = connection.createStatement();
            String locale = RequestHelper.getCurrentLocale();
            if ("en_GB".equalsIgnoreCase(locale)) {
                statement.execute("ALTER SESSION SET NLS_LANGUAGE=\'AMERICAN\'");
            } else {
                statement.execute("ALTER SESSION SET NLS_LANGUAGE=\'SIMPLIFIED CHINESE\'");
            }
        } finally {
            statement.close();
        }
    }
    return invocation.proceed();
}

}
在运行调试时发现代码无法执行到拦截逻辑,经过参考分页插件代码,发现需要重载以下方法(代码默认是只要实现intercept这个接口,但是实际上需要多加以下插件的处理逻辑才可以,才会启用Plugin的Proxy):

@Override
public Object plugin(Object target) {
    if (target instanceof StatementHandler) {
        return Plugin.wrap(target, this);
    }
    return target;
}

最终拦截器代码如下:
/**

  • <p>
  • 更改会话解析器
  • </p>
    *
  • @since 2021/7/14
    */

@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class AlterSessionInterceptor implements Interceptor {

@Override
public Object intercept(Invocation invocation) throws Throwable {
    Object[] args = invocation.getArgs();
    Connection connection = (Connection) args[0];
    if ("Oracle".equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) {
        Statement statement = null;
        try {
            statement = connection.createStatement();
            String locale = RequestHelper.getCurrentLocale();
            if ("en_GB".equalsIgnoreCase(locale)) {
                statement.execute("ALTER SESSION SET NLS_LANGUAGE=\'AMERICAN\'");
            } else {
                statement.execute("ALTER SESSION SET NLS_LANGUAGE=\'SIMPLIFIED CHINESE\'");
            }
        } finally {
            statement.close();
        }
    }
    return invocation.proceed();
}

@Override
public Object plugin(Object target) {
    if (target instanceof StatementHandler) {
        return Plugin.wrap(target, this);
    }
    return target;
}

@Override
public void setProperties(Properties properties) {
    // to do nothing
}

}

以上是关于springboot+mybatis拦截器不生效问题分析的主要内容,如果未能解决你的问题,请参考以下文章

mybatis的相同拦截器—切面执行的顺序

Mybatis的原理分析1(@Mapper是如何生效的)

SpringBoot + PageHelper, MyBatis分页不生效解决方案

Springboot 自定义mybatis 拦截器,实现我们要的扩展

mybatis update不生效

springboot拦截器不起作用