Mybatis---06Mybatis配置文件浅析(四)
参考链接:深入理解Mybatis插件开发
1.plugins:与其称为Mybatis插件,不如叫Mybatis拦截器,更加符合其功能定位,实际上它就是一个拦截器,应用代理模式,在方法级别上进行拦截。
1):支持拦截的方法
执行器Executor(update、query、commit、rollback等方法);
参数处理器ParameterHandler(getParameterObject、setParameters方法);
结果集处理器ResultSetHandler(handleResultSets、handleOutputParameters等方法);
SQL语法构建器StatementHandler(prepare、parameterize、batch、update、query等方法);
2):作用场景
分页功能:mybatis的分页默认是基于内存分页的(查出所有,再截取),数据量大的情况下效率较低,不过使用mybatis插件可以改变该行为,只需要拦截StatementHandler类的prepare方法,改变要执行的SQL语句为分页语句即可;
公共字段统一赋值:一般业务系统都会有创建者,创建时间,修改者,修改时间四个字段,对于这四个字段的赋值,实际上可以在DAO层统一拦截处理,可以用mybatis插件拦截Executor类的update方法,对相关参数进行统一赋值即可;
性能监控:对于SQL语句执行的性能监控,可以通过拦截Executor类的update, query等方法,用日志记录每个方法执行的时间;
其它:其实mybatis扩展性还是很强的,基于插件机制,基本上可以控制SQL执行的各个阶段,如执行阶段,参数处理阶段,语法构建阶段,结果集处理阶段,具体可以根据项目业务来实现对应业务逻辑。
3):小例子
A:创建一个自定义插件类MyPlugins,实现接口org.apache.ibatis.plugin.Interceptor,在类上使用注解@Intercepts设置拦截的类,类里面的方法,以及方法里面的参数
@Intercepts({ @Signature( type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) }) public class MyPlugins implements Interceptor { /** * 在此实现自己的拦截逻辑 * @param invocation Invocation参数中拿到执行方法的对象,方法,方法参数 * @return * @throws Throwable */ @Override public Object intercept(Invocation invocation) throws Throwable { Object target = invocation.getTarget(); //被代理对象 System.out.println(target); Method method = invocation.getMethod(); //代理方法 System.out.println(method); Object[] args = invocation.getArgs(); //方法参数 System.out.println(Arrays.toString(args)); System.out.println("我在拦截前"); // do something ...... 方法拦截前执行代码块 Object result = invocation.proceed(); System.out.println("我在拦截后"); // do something .......方法拦截后执行代码块 return result; } /** * 生成代理对象 * @param target * @return */ @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } /** * 设置一些属性变量 * @param properties */ @Override public void setProperties(Properties properties) { //输出设置的配置参数 Iterator iterator = properties.keySet().iterator(); while (iterator.hasNext()){ String keyValue = String.valueOf(iterator.next()); System.out.println(properties.getProperty(keyValue)); } } }
B:在mybatis配置文件mybatis-config.xml注册,并设置一些参数
<plugins> <plugin interceptor="com.james.mybatis.plugins.MyPlugins"> <property name="name" value="zhangsan"/> </plugin> </plugins>
C:在测试类中测试:
public class Main { public static void main(String[] args) throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); //2.创建 SqlSessionFactory 的构建者对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //3.使用构建者创建工厂对象 SqlSessionFactory,在配置文件中设置的plugins标签参数在执行这个是被使用 SqlSessionFactory factory = builder.build(in); //4.使用 SqlSessionFactory 生产 SqlSession 对象 SqlSession session = factory.openSession(); //5.使用 SqlSession 创建 dao 接口的代理对象 IBookDao bookDao = session.getMapper(IBookDao.class); //6.使用代理对象执行查询所有方法,执行这个方法是会被自己实现的插件类进行拦截 Book book = bookDao.selectById(1); System.out.println(book); //7.释放资源 session.close(); in.close(); } }

浙公网安备 33010602011771号