MyBatis 允許你在已映射語句執行過程中的某一點進行攔截調用。默認情況下,MyBatis 允許使用插件來攔截的方法調用包括:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)ParameterHandler (getParameterObject, setParameters)ResultSetHandler (handleResultSets, handleOutputParameters)StatementHandler (PRepare, parameterize, batch, update, query)這些類中方法的細節可以通過查看每個方法的簽名來發現,或者直接查看 MyBatis 的發行包中的源代碼。 假設你想做的不僅僅是監控方法的調用,那么你應該很好的了解正在重寫的方法的行為。 因為如果在試圖修改或重寫已有方法的行為的時候,你很可能在破壞 MyBatis 的核心模塊。 這些都是更低層的類和方法,所以使用插件的時候要特別當心。
通過 MyBatis 提供的強大機制,使用插件是非常簡單的,只需實現 Interceptor 接口,并指定了想要攔截的方法簽名即可。
把Mybatis所有執行的sql都記錄下來。
通過對 MyBatis org.apache.ibatis.executor.statementStatementHandler 中的prepare 方法進行攔截即可。
prepare 方法簽名如下:
Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException;自定義一個類,實現 org.apache.ibatis.pluginInterceptor 接口,代碼如下:
package com.bytebeats.mybatis3.interceptor;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.plugin.*;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.sql.Connection;import java.util.Properties;/** * ${DESCRipTION} * * @author Ricky Fung * @date 2017-02-17 11:52 */@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class}) })public class SQLStatsInterceptor implements Interceptor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); BoundSql boundSql = statementHandler.getBoundSql(); String sql = boundSql.getSql(); logger.info("mybatis intercept sql:{}", sql); return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { String dialect = properties.getProperty("dialect"); logger.info("mybatis intercept dialect:{}", dialect); }}這樣一個插件就開發完成了,接下來需要在 mybatis-config.xml 文件中增加 plugins節點,完整配置如下:
<?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> <plugin interceptor="com.bytebeats.mybatis3.interceptor.SQLStatsInterceptor"> <property name="dialect" value="MySQL" /> </plugin> </plugins></configuration>spring-mybatis.xml
<?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <util:properties id="db" location="classpath:db.properties"/> <!-- 配置數據源 --> <bean name="parentDatasource" abstract="true" class="com.alibaba.druid.pool.DruidDataSource"> <!-- 初始化連接大小 --> <property name="initialSize" value="1" /> <!-- 連接池最大使用連接數量 --> <property name="maxActive" value="100" /> <!-- 連接池最小空閑 --> <property name="minIdle" value="20" /> <!-- 獲取連接最大等待時間 --> <property name="maxWait" value="30000" /> <property name="validationQuery" value="SELECT 1" /> <property name="testOnBorrow" value="true" /> <property name="testOnReturn" value="true" /> <property name="testWhileIdle" value="true" /> <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="25200000" /> <!-- 打開removeAbandoned功能 --> <property name="removeAbandoned" value="true" /> <!-- 1800秒,也就是30分鐘 --> <property name="removeAbandonedTimeout" value="1800" /> <!-- 關閉abanded連接時輸出錯誤日志 --> <property name="logAbandoned" value="true" /> <!-- 監控數據庫 --> <property name="filters" value="mergeStat" /> </bean> <!-- trade數據源 --> <bean name="trade" init-method="init" destroy-method="close" parent="parentDatasource"> <property name="driverClassName" value="#{db['trade.jdbc.driverClassName']}" /> <property name="url" value="#{db['trade.jdbc.url']}" /> <property name="username" value="#{db['trade.jdbc.username']}" /> <property name="passWord" value="#{db['trade.jdbc.password']}" /> </bean> <!-- admin數據源 --> <bean name="admin" init-method="init" destroy-method="close" parent="parentDatasource"> <property name="driverClassName" value="#{db['admin.jdbc.driverClassName']}" /> <property name="url" value="#{db['admin.jdbc.url']}" /> <property name="username" value="#{db['admin.jdbc.username']}" /> <property name="password" value="#{db['admin.jdbc.password']}" /> </bean> <!--trade mybatis config--> <bean id="tradeSqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="trade" /> <property name="mapperLocations" value="classpath*:mapper/trade/*Mapper.xml" /> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="typeAliasesPackage" value="com.bytebeats.mybatis3.domain.trade" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.bytebeats.mybatis3.mapper.trade" /> <property name="sqlSessionFactoryBeanName" value="tradeSqlSessionFactory" /> </bean> <!--admin mybatis config--> <bean id="adminSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="admin" /> <property name="mapperLocations" value="classpath*:mapper/admin/*Mapper.xml" /> <property name="typeAliasesPackage" value="com.bytebeats.mybatis3.domain.admin" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.bytebeats.mybatis3.mapper.admin" /> <property name="sqlSessionFactoryBeanName" value="adminSqlSessionFactory" /> </bean> <!-- 配置事務 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="trade" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /></beans>MyBatis 插件(plugins)教程:http://www.mybatis.org/mybatis-3/zh/configuration.html#plugins
mybatis3-best-practice
新聞熱點
疑難解答