MyBatis拦截器
MyBatis拦截器作用
Mybatis可以在执行sql语句的过程中,织入一些拦截器,在不同的节点修改修改一些执行过程中的关键属性,从而影响SQL的生成、执行和返回结果。
MyBatis拦截器提供的扩展点
拦截执行器方法org.apache.ibatis.executor.Executor
点击查看代码
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
int update(MappedStatement ms, Object parameter) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
List<BatchResult> flushStatements() throws SQLException;
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
boolean isCached(MappedStatement ms, CacheKey key);
void clearLocalCache();
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
Transaction getTransaction();
void close(boolean forceRollback);
boolean isClosed();
void setExecutorWrapper(Executor executor);
}
拦截SQL语法构建处理org.apache.ibatis.executor.statement.StatementHandler
点击查看代码
public interface StatementHandler {
// 创建JDBC Statement对象,并完成Statement对象的属性设置
Statement prepare(Connection connection, Integer transactionTimeout)
throws SQLException;
// 使用MyBatis中的ParameterHandler组件为PreparedStatement和CallableStatement参数占位符设置值。
void parameterize(Statement statement)
throws SQLException;
// 将SQL命令添加到批处量执行列表中。
void batch(Statement statement)
throws SQLException;
// 调用Statement对象的execute()方法执行更新语句,例如UPDATE、INSERT、DELETE语句。
int update(Statement statement)
throws SQLException;
// 执行查询语句,并使用ResultSetHandler处理查询结果集。
<E> List<E> query(Statement statement, ResultHandler resultHandler)
throws SQLException;
// 带游标的查询返回Cursor对象。
<E> Cursor<E> queryCursor(Statement statement)
throws SQLException;
// 获取Mapper中配置的SQL信息,BoundSql封装了动态SQL解析后的SQL文本和参数映射信息。
BoundSql getBoundSql();
// 获取ParameterHandler实例。
ParameterHandler getParameterHandler();
}
拦截参数处理org.apache.ibatis.executor.parameter.ParameterHandler
点击查看代码
public interface ParameterHandler {
Object getParameterObject();
void setParameters(PreparedStatement ps) throws SQLException;
}
拦截结果集处理org.apache.ibatis.executor.resultset.ResultSetHandler
点击查看代码
public interface ResultSetHandler {
<E> List<E> handleResultSets(Statement stmt) throws SQLException;
<E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;
void handleOutputParameters(CallableStatement cs) throws SQLException;
}
各种拦截器的关系图:
MyBatis拦截器用法
拦截器提供的注解
@Intercepts
作用:标识当前类为拦截器类
@Signature
作用:
type:就是指定拦截器类型(ParameterHandler ,StatementHandler,ResultSetHandler )
method:是拦截器类型中的方法,不是自己写的方法
args:是method中方法的入参
MyBatis拦截器入门例子
@Slf4j
@Component
@Intercepts(value = {
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class FirstInterceptor implements Interceptor {
/**
* 拦截方法逻辑
* 这里主要是通过反射去获取要执行的SQL相关信息,然后进行操作
* @param invocation
* @return
* @throws Throwable
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 代理方法
log.info("=============== method = " + invocation.getMethod().getName());
// 代理方法参数
Object[] args = invocation.getArgs();
Statement statement = (Statement) args[0];
// 被代理的对象
log.info("=============== args = " + invocation.getTarget());
// 执行目标方法
Object result = invocation.proceed();
log.info("=============== result = " + result);
return result;
}
/**
* 生成MyBatis拦截器代理对象
* @param target
* @return
*/
@Override
public Object plugin(Object target) {
if (target instanceof ResultSetHandler) {
return Plugin.wrap(target, this);
}
return target;
}
/**
* 设置插件属性(直接通过Spring的方式获取属性,所以这个方法一般也用不到)
* 项目启动的时候数据就会被加载
* @param properties
*/
@Override
public void setProperties(Properties properties) {
}
}
结果: