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
新闻热点
疑难解答