关于Mybatis框架中Interceptor接口的简单使用

关于Mybatis中插件的声明需要在configuration的配置文件中进行配置,配置文件的位置使用configLocation属性指定。测试中使用的config文件内容如下:

<?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>

    <!--plugins插件之 分页拦截器  -->
    <plugins>
        <plugin interceptor="com.interceptors.LogInterceptor" ></plugin>
    </plugins>

</configuration>

在配置文件中配置了一个Interceptor的实现类,LogInterceptor的代码如下:

public class LogInterceptor implements Interceptor{
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("LogInterceptor : intercept");
        return null;
    }

    @Override
    public Object plugin(Object target) {
        if(target instanceof StatementHandler){
            RoutingStatementHandler handler = (RoutingStatementHandler)target;
            //打印出当前执行的sql语句
            System.out.println(handler.getBoundSql().getSql());
        }

        return target;
    }

    @Override
    public void setProperties(Properties properties) {
        System.out.println("LogInterceptor : setProperties");
    }
}

在工程的配置文件中,在配置SqlSessionFactoryBean时需要指明config配置文件的位置,配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <bean id="user1" class="com.beans.User">
        <property name="userName" value="zhuyuqiang"/>
    </bean>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="name" value="mysql"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/world"/>
        <property name="username" value="root"/>
        <property name="password" value="zh4y4q5ang"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:mybatis/*.xml"/>
        <property name="typeAliasesPackage" value="com.entities"/>
        <property name="configLocation" value="classpath:config/configuration.xml"/>
    </bean>
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.interfaces"/>
    </bean>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <context:component-scan base-package="com"/>
</beans>

基本上这样配置以后,在工程中声明的plugin就已经生效了,实际中打印出来的log如下:

SELECT * FROM city WHERE ID=?

执行的CityMapper如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.interfaces.CityMapper">
<resultMap id="BaseResultMap" type="com.entities.City">
    <id column="ID" jdbcType="INTEGER" property="id"/>
    <result column="Name" jdbcType="CHAR" property="name"/>
    <result column="CountryCode" jdbcType="CHAR" property="countrycode"/>
    <result column="District" jdbcType="CHAR" property="district"/>
    <result column="Population" jdbcType="INTEGER" property="population"/>
</resultMap>
<select id="selectCityById" parameterType="int" resultType="com.entities.City">
    SELECT * FROM city WHERE ID=#{id,jdbcType=INTEGER}
</select>
</mapper>

简单的测试了一下,可以打印出sql语句。在使用mybatis提供的plugin接口时需要注意,在构建ParameterHandler 、ResultSetHandler 、StatementHandler 和Executor 的时候都会调用在项目中实现的插件接口,一般情况下,如果只是为了打印显示当前执行的sql语句,可以只在当target为StatementHandler类型的时候再进行处理即可。

  public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
  }

  public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,
      ResultHandler resultHandler, BoundSql boundSql) {
    ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
    resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
    return resultSetHandler;
  }

  public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
      System.out.println("newStatementHandler......");
      StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    return statementHandler;
  }

  public Executor newExecutor(Transaction transaction) {
    return newExecutor(transaction, defaultExecutorType);
  }

  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

在实际测操作中,在项目中定义实现的plugin都会被添加保存到interceptorChain对象的一个集合中,在内部会对集合里的对象进行遍历,分别调用每个插件的plugin方法。
其中target就是在调用pluginAll传入的具体对象。。。

猜你喜欢

转载自blog.csdn.net/u011043551/article/details/80625167