181. Spring Boot MyBatis自定义Plugin

à SpringBoot视频

http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à SpringCloud视频

http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à Spring Boot源码

https://gitee.com/happyangellxq520/spring-boot

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532

 

需求缘起:

       在网易云课堂的讨论区(传送门)中有人咨询:老师,PageHelper的实现原理是怎么样的?这个原理吧,当然不是一两句话就能说明白的,所以这里打算撰文说下。

 

本节大纲:

写道
一、自定义插件的思路
二、自定义插件编码:记录SQL

 

 

一、自定义插件的思路

 

1.1 实现接口Interceptor

 

要在mybatis自定义插件的话,那么要实现如下接口:

org.apache.ibatis.plugin.Interceptor

     

  在此接口中主要有三个方法:

 

 

Java代码   收藏代码
  1. Object intercept(Invocation invocation) throws Throwable;  
  2. Object plugin(Object target);  
  3. void setProperties(Properties properties);  
 

 

 

       那么这三个都是都能干嘛呢?

 

(1)方法plugin(Object target)

plugin方法是拦截器用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理。当返回的是代理的时候我们可以对其中的方法进行拦截来调用intercept方法,当然也可以调用其他方法。

 

(2)方法setProperties(Properties properties)

setProperties方法是用于在Mybatis配置文件中指定一些属性的。

 

(3)方法intercept(Invocation invocation)

定义自己的Interceptor最重要的是要实现plugin方法和intercept方法,在plugin方法中我们可以决定是否要进行拦截进而决定要返回一个什么样的目标对象。而intercept方法就是要进行拦截的时候要执行的方法。

 

 1.2 使用@Bean注入自定义的Plugin

       在spring boot中可以使用如下代码进行注入:

 

Java代码   收藏代码
  1. @Bean  
  2.     public SQLStatsInterceptor sqlStatsInterceptor(){  
  3.         SQLStatsInterceptor sqlStatsInterceptor = new SQLStatsInterceptor();  
  4.         Properties properties = new Properties();  
  5.         properties.setProperty("dialect""mysql");  
  6.          sqlStatsInterceptor.setProperties(properties);  
  7.        return sqlStatsInterceptor;  
  8. }  
 

 

       如果是在spring中使用xml配置的方式的话,可以使用如下的方式进行注入:

Xml代码   收藏代码
  1. <configuration>  
  2.     <plugins>  
  3.         <plugin interceptor="com.kfit.config.interceptor.SQLStatsInterceptor">  
  4.             <property name="dialect" value="mysql" />  
  5.         </plugin>  
  6.     </plugins>  
  7. </configuration>  
  8.    

 

 

 

1.3 思路总结

       上面那多废话,简单来说就是:其一需要定义实现接口Interceptor;其二就是要配置注入。千言万语, 不如一句代码,还是写个例子看看效果吧。

                             

二、自定义插件编码:记录SQL

 

2.1 需求描述

       在这里实现:把Mybatis所有执行的sql都记录下来。

 

2.2 代码实现分析

通过对 MyBatis 的org.apache.ibatis.executor.statement.StatementHandler中的prepare 方法进行拦截即可。

 

 

2.3 代码实现

2.3.1实现类SQLStatsInterceptor实现接口Interceptor

Java代码   收藏代码
  1. package com.kfit.config.interceptor;  
  2. import java.sql.Connection;  
  3. import java.util.Properties;  
  4. import org.apache.ibatis.executor.statement.StatementHandler;  
  5. import org.apache.ibatis.mapping.BoundSql;  
  6. import org.apache.ibatis.plugin.Interceptor;  
  7. import org.apache.ibatis.plugin.Intercepts;  
  8. import org.apache.ibatis.plugin.Invocation;  
  9. import org.apache.ibatis.plugin.Plugin;  
  10. import org.apache.ibatis.plugin.Signature;  
  11.    
  12. @Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class,Integer.class})})  
  13. public class SQLStatsInterceptor implements Interceptor {  
  14.    
  15.     @Override  
  16.     public Object intercept(Invocation invocation) throws Throwable {  
  17.        StatementHandler statementHandler= (StatementHandler) invocation.getTarget();  
  18.        BoundSql boundSql = statementHandler.getBoundSql();  
  19.        System.out.println(boundSql.getSql());  
  20.        return invocation.proceed();  
  21.     }  
  22.    
  23.     @Override  
  24.     public Object plugin(Object target) {  
  25.        return Plugin.wrap(target, this);  
  26.     }  
  27.    
  28.     @Override  
  29.     public void setProperties(Properties properties) {  
  30.         String dialect = properties.getProperty("dialect");  
  31.         System.out.println("dialect="+dialect);  
  32.     }  
  33. }  

 

代码分析:

(1)首先SQLStatsInterceptor类实现了接口Interceptor;

(2)需要重写3个方法,核心的拦截处理方法是intercept,在这个方法中可以获取到对应的绑定的sql,在这里作为演示只是打印了SQL,如果需要可以保存起来。

(3)在方法上有一个很重要的注解@Intercepts,在此注解上配置的注解说明了要拦截的类(type=StatementHandler.class),拦截的方法(method="prepare"),方法中的参数(args={Connection.class,Integer.class}),也就是此拦截器会拦截StatementHandler类中的如下方法:

 

Java代码   收藏代码
  1. Statement prepare(Connection connection, Integer transactionTimeout)  

  

      

 

这里顺带提一下,可以拦截的类:

StatementHandler (prepare, parameterize, batch, update, query)

ResultSetHandler (handleResultSets, handleOutputParameters)

ParameterHandler (getParameterObject, setParameters)

Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)

 

 

2.3.2定义配置类进行注入

Java代码   收藏代码
  1. @Configuration  
  2. public class MyBatisConfiguration {  
  3.     @Bean  
  4.     public SQLStatsInterceptor sqlStatsInterceptor(){  
  5.         SQLStatsInterceptor sqlStatsInterceptor = new SQLStatsInterceptor();  
  6.         Properties properties = new Properties();  
  7.         properties.setProperty("dialect""mysql");  
  8.          sqlStatsInterceptor.setProperties(properties);  
  9.        return sqlStatsInterceptor;  
  10.     }  
  11. }  

 

       到这里就可以测试使用了。一旦懂了自定义Plugin后,那么对于PageHelper的实现也就明白了七八分了




http://412887952-qq-com.iteye.com/blog/2409334

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值