下面是详细讲解“mybatis 自定义实现拦截器插件Interceptor示例”的完整攻略:
什么是MyBatis拦截器?
MyBatis 拦截器是一种插件技术,可自定义MyBatis框架自身的行为,是MyBatis框架中的重要组成部分。MyBatis 内置提供了多种拦截器,例如 Executor
、StatementHandler
等,每种拦截器都实现了不同的拦截点,拦截器具体实现方法是使用JDK 代理
或者CGLIB 代理
实现,通过对目标对象进行代理,可以拦截目标对象的方法调用,从而达到修改目标对象行为、增强功能等目的。
自定义拦截器示例1
在MyBatis总拦截器链执行前统计出SQL执行的时间。
// 定义拦截器类
public class SqlCostInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 获取StatementHandler
StatementHandler stmtHandler = (StatementHandler) invocation.getTarget();
// 获取被代理方法名称
String methodId = invocation.getMethod().getName();
MappedStatement mappedStatement = null;
if (invocation.getTarget() instanceof RoutingStatementHandler) {
// 分离代理对象链,即获取代理对象的真正对象
RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
// 使用反射获取mappedStatement属性值
mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(statementHandler, "delegate.mappedStatement");
} else if (invocation.getTarget() instanceof PreparedStatementHandler) {
// 分离代理对象链,即获取代理对象的真正对象
PreparedStatementHandler statementHandler = (PreparedStatementHandler) invocation.getTarget();
// 使用反射获取mappedStatement属性值
mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(statementHandler, "delegate.mappedStatement");
}
// 获取sql语句
BoundSql boundSql = stmtHandler.getBoundSql();
String sql = boundSql.getSql();
Object[] args = invocation.getArgs();
// 获取SQL执行时间
long start = System.currentTimeMillis();
// 打印sql语句
System.out.println(">>>>>>>>>>> 执行的sql语句为: " + sql);
Object result = invocation.proceed();
if (null != mappedStatement) {
// 获取操作类型
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
System.out.println(">>>>>>>>>>> 操作类型为: " + sqlCommandType);
}
// 输出SQL执行时间
System.out.println(">>>>>>>>>>> SQL执行时间为:" + (System.currentTimeMillis() - start) + "ms");
return result;
}
@Override
public Object plugin(Object target) {
// 使用默认的Plugin.wrap方法生成代理对象
return Plugin.wrap(target, this);
}
}
在示例中,我们通过自定义实现 Interceptor
接口,完成了对SQL语句执行前的统计SQL执行时间的功能。首先我们通过 invocation.getTarget()
获取到具体的执行方法对象,通过获取到的对象获取被代理方法名称、mappedStatement和BoundSql等信息,最后通过invocation.proceed()
实现对方法的调用,记录SQL语句执行的时间。
<!-- 将自定义拦截器注册到配置文件 -->
<plugins>
<plugin interceptor="com.example.plugin.SqlCostInterceptor"></plugin>
</plugins>
将自定义的 SqlCostInterceptor
拦截器注册到 Ibatis 的核心配置文件中,如上所示。
自定义拦截器示例2
在MyBatis执行增删改操作时自动填充 createTime 和 updateTime 字段。
// 定义自定义插件类
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class CreateAndUpdateTimePlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
if (target instanceof Executor) {
MappedStatement stmt = (MappedStatement) invocation.getArgs()[0];
SqlCommandType sqlCommandType = stmt.getSqlCommandType();
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
Object parameterObject = invocation.getArgs()[1];
if (parameterObject instanceof BaseEntity) {
BaseEntity entity = (BaseEntity) parameterObject;
Date date = new Date();
if (SqlCommandType.INSERT.equals(sqlCommandType)) {
entity.setCreateTime(date);
entity.setUpdateTime(date);
} else if (SqlCommandType.UPDATE.equals(sqlCommandType)) {
entity.setUpdateTime(date);
}
}
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
}
<!-- 在mybatis中注册该自定义插件 -->
<plugins>
<plugin interceptor="com.example.plugin.CreateAndUpdateTimePlugin"></plugin>
</plugins>
在示例2中,我们针对MyBatis新增、更新等操作,自定义实现插件类 CreateAndUpdateTimePlugin
,对实体类中的createTime和updateTime进行自动填充。当增删改操作被执行时,判断是否需要对createTime和updateTime进行赋值,并执行插入或更新操作。最后将自定义的 CreateAndUpdateTimePlugin
插件注册到 Ibatis 的核心配置文件中。
以上就是MyBatis自定义实现拦截器插件Interceptor的两个示例。通过示例的讲解,希望能够帮助读者更好的了解MyBatis拦截器的原理和使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis 自定义实现拦截器插件Interceptor示例 - Python技术站