1. 程式人生 > >關於Mybatis框架中Interceptor介面的簡單使用

關於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傳入的具體物件。。。