天天看点

实现Mybatis拦截器

身为一个没发过任何博客的小白女程序员,要开始写博客啦!

最近在做公司项目时,Client端做资源缓存时候需要根据Server端的数据库表是否更新来刷新,因此在Server端如果某个表内容发生改变,那么这个表的版本号需要+1。需要监控的业务核心表不多,因此采用了通过实现Mybatis拦截器获取sql内容来实现对表版本的更新,更新的版本号存储位置可根据业务场景来决定,redis或者数据库等等。

因为是如果表内容更新,所以本次业务需要拦截的是insert\update\delete三种情况。

项目是SpringBoot的,下面来简单说下大体流程~~

1、自定义拦截器类实现 org.apache.ibatis.plugin.Interceptor接口

@Intercepts注解需要一个Signature(拦截点)参数数组,来指定拦截哪个对象里面的哪个方法。

Mybatis中所有的Mapper语句的执行都是通过Executor进行的。Executor是Mybatis的核心接口。在其定义的接口方法可以看出,对应的增删改语句是通过Executor接口的update方法进行的,因此这里选择方法update。

业务操作写在intercept方法里,但需注意如果执行过程中出现异常不能影响主流程。

拿到sql后,可拿到sql的执行操作类型、参数值等,如果需要获取sql中的表名称,则其可通过引入jsqlparser包写个工具类得到。

@Intercepts({

@Signature(type = Executor.class, method = “update”, args = {MappedStatement.class, Object.class})

})

@Slf4j

@Component

public class MybatisInterceptor implements Interceptor {

@Override
public Object intercept(Invocation invocation) throws Throwable {
	Object[] args = invocation.getArgs();
	MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
	SqlCommandType commandType = ms.getSqlCommandType();
	try {
		//获取到原始sql语句
		Object parameterObject = args[1];
		BoundSql boundSql = ms.getBoundSql(parameterObject);
		String sql = boundSql.getSql();
		log.info("获取到的SQL:{}", sql);
		//业务操作
	} catch (Exception e) {
		log.error("XXXXX: {}", e.getMessage());
	}

	return invocation.proceed();
}

@Override
public Object plugin(Object target) {
	return Plugin.wrap(target, this);
}

@Override
public void setProperties(Properties properties) {

}
           

}

代码中可看到对类添加了@component 注解,可纳入进spring容器中进行管理,因此也无需再额外配置等,启动项目拦截器即可生效。

当然由于不同业务,此文章只针对在个人做的业务过程中的一个分享,仅做参考~~