關於Mybatis框架中Interceptor介面的簡單使用
阿新 • • 發佈:2019-01-23
關於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傳入的具體物件。。。