mybatis plugin

大家都是知道了,mybatis可以通过自定义插件实现分页功能,很多博客中都说过了,这是拦截器的形式。既然是拦截器实现的分页,那么拦截器拦截的是什么呢?拦截以后我们应该做什么呢?搞懂这两个问题就明白这个分页的拦截器是怎么回事儿了。其实拦截器不仅仅这点作用。进入正题。
mybatis官网中说明了,mybatis plugin可以拦截四个类系的对象:Executor,ParameterHandler, ResultSetHandler ,StatementHandler ;而我们要拦截的无非也就是Dao中的方法。不要急往下读
Executor:这个相当于就是mybatis调用jdbc的执行器,这里的功能就多了,大致包含查询、更新,提交事务,回滚等等;
ParameterHandler:这个相当于是专门处理被拦截方法中的参数,比如要将拦截的方法的参数中加一个值、或是验证一下什么的、或是修一下值;
ResultSetHandler :这个就简单了寒,很明显就是拦截方法返回的结果,对结果集进行再加工;

StatementHandler :这个一个是不是很熟悉,JDBC和它就相关了。分页就可以使用它也来处理了,获得原来的sql,再进行处理加工成分页的sql,最终就可以实现。

我们回过头来看看,定义一个拦截器,当然是实现mybatis的Interceptor,如下:
public class PageInterceptor implements Interceptor {
,这里要实现他的三个方法,分别是
@Intercepts({ @Signature(args = { Connection.class }, method = “prepare”, type = StatementHandler.class) })
public class PageInterceptor implements Interceptor {
/*
* 这个方法很很明显就是算是,拦截器要做什么的地方,大家看到invocation这个就应该熟悉了,
* 反射,不多说。通过反射就可以获取到目标对象,参数,和方法名。注意这里的方法名不是dao的中方法名。
方法中的代码很简单了吧。
*/
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statement = (StatementHandler) invocation.getTarget();
BoundSql boundSql = statement.getBoundSql();
Object parameterObject = boundSql.getParameterObject();
//此处的parameterObject为被拦截DAO方法的参数,比如这个Dao的参数可以为一个page对象,对象属性包含当前面,每页显示的行数,总页数,总行数,当前页的结果集(一般为一个List),以及一个集合(前端传递过来的,查询条件集合)
System.err.println(parameterObject);
String sql = boundSql.getSql();
//这里获得原来sql后,就可以进行改造了,处理为查询总数据的即可。
System.err.println(sql);
Connection connectin = (Connection) invocation.getArgs()[0];
//此处获取到的就是prepare方法。
return invocation.proceed();
}

/*
* 这里多说一下,这是就是包装前面所说的mybait提供中的四个类系对象,这个方法会被执行四次。具体被包装的是哪个看具体的配置。当前被包装就是StatementHandler类系的对象(类的注解上面标识出来了),没有被包装的对象,原样返回,被装的就返回代理对象。
*/
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}

/*这个方法就是获取外部xml中配置property的key,如下
<plugins>
        <plugin interceptor="com.liuhao.stu.PageInterceptor">
            <property name="dialect" value="mysql" />
            <property name="pageSqlId" value=".*ListPage.*" />
        </plugin>
    </plugins>

这里有一点很重要,就是这组标签在配置拦截器时,要放到最前面,不然XML报错,很无解。这个属性配置就很有用了哈,比如当前拦截的是什么数据库,就可以通过这里来区分了;拦截什么样了DAO方法也可以在这里实现了,比如以ListPage、paging,page结尾的。当拦截的就是包含ListPage的DAO方法都会被拦截
*/
public void setProperties(Properties p) {
String dialect = p.getProperty(“dialect”);
String pageSqlId = p.getProperty(“pageSqlId”);
}
}


通过以上说明,大家应该发现一点,就是DAO方法被拦截后,会先加载xml中的属性配置,也就是先执行setProperties这个方法,然后对这四个类型的实例对象进行包装,也就是执行plugin方法(注解配置谁,就包装谁,并返回代理对象,未包装的直接返回原对象),最后执行intercept方法,完成具体的执行。

最后总结一下就是:通过xml的plugin配置,拦截对应的DAO方法;然后在自定义拦截器中,配置注释,我们具体要做的事(是加工SQL、是处理结果集、是处理参数、还是处理执行器,以及他们对应的方法和参数);明确后,就是调用到wrap方法了,对具体的对象进行包装,并返回;最后执行intercept方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhjwyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值