欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MyBatis Excutor 拦截器的巧妙用法

程序员文章站 2024-04-01 20:27:52
这里要讲的巧妙用法是用来实现在拦截器中执行额外 mybatis 现有方法的用法。 并且会提供一个解决拦截executor时想要修改mappedstatement时解决并发...

这里要讲的巧妙用法是用来实现在拦截器中执行额外 mybatis 现有方法的用法。

并且会提供一个解决拦截executor时想要修改mappedstatement时解决并发的问题。

这里假设一个场景:

实现一个拦截器,记录 mybatis 所有的 insert,update,delete 操作,将记录的信息存入数据库。

这个用法在这里就是将记录的信息存入数据库。

实现过程的关键步骤和代码:

1.首先在某个 mapper.xml 中定义好了一个往日志表中插入记录的方法,假设方法为id="insertsqllog"。

2.日志表相关的实体类为sqllog.

3.拦截器签名:

@intercepts({@org.apache.ibatis.plugin.signature(
  type=executor.class, 
  method="update", 
  args={mappedstatement.class, object.class})})
public class sqlinterceptor implements interceptor

4.接口方法简单实现:

public object intercept(invocation invocation) throws throwable {
  object[] args = invocation.getargs();
  mappedstatement ms = (mappedstatement) args[0];
  object parameter = args[1];
  sqllog log = new sqllog();
  configuration configuration = ms.getconfiguration();
  object target = invocation.gettarget();
  statementhandler handler = configuration.newstatementhandler((executor) target, ms, 
       parameter, rowbounds.default, null, null);
  boundsql boundsql = handler.getboundsql();
  //记录sql
  log.setsqlclause(boundsql.getsql());
  //执行真正的方法
  object result = invocation.proceed();
  //记录影响行数
  log.setresult(integer.valueof(integer.parseint(result.tostring())));
  //记录时间
  log.setwhencreated(new date());
  //todo 还可以记录参数,或者单表id操作时,记录数据操作前的状态
  //获取insertsqllog方法
  ms = ms.getconfiguration().getmappedstatement("insertsqllog");
  //替换当前的参数为新的ms
  args[0] = ms;
  //insertsqllog 方法的参数为 log
  args[1] = log;
  //执行insertsqllog方法
  invocation.proceed();
  //返回真正方法执行的结果
  return result;
}

重点 

mappedstatement是一个共享的缓存对象,这个对象是存在并发问题的,所以几乎任何情况下都不能去修改这个对象(通用mapper除外),想要对mappedstatement做修改该怎么办呢?

并不难,executor中的拦截器方法参数中都有mappedstatement ms,这个ms就是后续方法执行要真正用到的mappedstatement,这样一来,问题就容易解决了,根据自己的需要,深层复制mappedstatement对象中自己需要修改的属性,然后修改这部分属性,之后将修改后的ms通过上面代码中args[0]=ms这种方式替换原有的参数,这样就能实现对ms的修改而且不会有并发问题了。

这里日志的例子就是一个更简单的应用,并没有创建ms,只是获取了一个新的ms替换现有的ms,然后去执行。

总结

以上所述是小编给大家介绍的mybatis excutor 拦截器的巧妙用法,希望对大家有所帮助