背景
MyBatis3提供了一个插件机制,用于扩展Mybatis的功能,基本配置模式比较简单:实现插件类、然后配置。
配置方法
配置方法有两种,一种是mybatis自带的、不适用spring的方式,另外一种就是基于Spring的了。因为UCore使用了Spring,所以第一种方式不展示,主要展示第二种(第一种在官方文档中有)
实现插件类
插件类基本代码框架如下
02 | @Intercepts ({ @Signature ( |
05 | args = {MappedStatement. class , Object. class , RowBounds. class , ResultHandler. class })}) |
06 | public class MysqlPagePlugin implements Interceptor { |
08 | public Object intercept(Invocation invocation) throws Throwable { |
09 | System.out.print( "ok2" ); |
15 | public Object plugin(Object target) { |
16 | return Plugin.wrap(target, this ); |
20 | public void setProperties(Properties properties) { |
拦截之后,就在intercept方法中编写内容了,在传入的参数中可以获得拦截点的资料,可以传入Statement、调用参数等内容过来。
添加Spring配置文件
Spring的配置文件主要放在SqlSessionFactory中,配置代码如下:
01 | < bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" > |
02 | < property name = "dataSource" ref = "mysql_dataSource" /> |
03 | < property name = "mapperLocations" > |
05 | < value >classpath:/cn/ctyun/*/*/*Mapper.xml</ value > |
08 | < property name = "plugins" > |
10 | < bean class = "cn.ctyun.core.base.dao.mybatis.Interceptors.MysqlPagePlugin" /> |
简单说来,就是注册plugins属性,就完成配置了。
原理
从插件代码中可以看到,插入的时候使用了一个注解来标注:
1 | @Intercepts ({ @Signature ( |
4 | args = {MappedStatement. class , Object. class , RowBounds. class , ResultHandler. class })}) |
有很奇怪的参数:type、method、args,很像反射的模式。实际上,Mybatis的插件机制就是一种反射,针对executor、parameter、resultHandlerr等(有4种,但是不重要了),每次调用的时候拦截器生成一个调用方法,然后反射调用。
查看Executor接口的时候,正好有一个方法名为query,其入参为args中的内容。
在官方文档上摘抄的四种Executor类型:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
结论
因为拦截器使用的时候实在是反射用得太多,灵活过头了,所以暂时不用,准备用Spring的动态代理类来重新实现这种Mapper机制。