MyBatis学习——第四篇(拦截器和拦截器分页实现)

MyBatis架构体图


1:mybatis核心对象
从MyBatis代码实现的角度来看,MyBatis的主要的核心部件有以下几个:

SqlSession            作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
Executor              MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
StatementHandler   封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler   负责对用户传递的参数转换成JDBC Statement 所需要的参数,
ResultSetHandler    负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
TypeHandler          负责java数据类型和jdbc数据类型之间的映射和转换
MappedStatement   MappedStatement维护了一条<select|update|delete|insert>节点的封装, 
SqlSource            负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
BoundSql             表示动态生成的SQL语句以及相应的参数信息
Configuration        MyBatis所有的配置信息都维持在Configuration对象之中。
它们的关系如下图所示:

如果想要对这四大对象进行操作可以用插件实现拦截操作,故插件就是拦截器

它们都是sqlSession的底层类实现,也是插件能够拦截的四大对象。所以这里已经触及了MyBATIS的底层,动态代理,反射随时可以看到。了解他们的协作,是插件编写的基础之一,所以这是十分的重要。

 

2:mybatis拦截器
第一步首先在Mybatis配置文件中配置拦截器插件

    <!--配置插件  -->
    <plugins>
        <plugin interceptor="com.thit.interceptor.Myinterceptor1">
            <property name="shuxing1" value="value1"/>
            <property name="shuxing2" value="value11"/>
        </plugin>
        <plugin interceptor="com.thit.interceptor.Myinterceptor2">
            <property name="shuxing1" value="value2"/>
            <property name="shuxing2" value="value22"/>
        </plugin>
        <!-- com.github.pagehelper为PageHelper类所在包名 ,pagehelper分页工具-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
            <property name="param1" value="value1"/>
        </plugin>
    </plugins>
然后创建这两个拦截器:

拦截器1代码如下

package com.thit.interceptor;
 
import java.sql.Statement;
import java.util.Properties;
 
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
 
 
import org.apache.ibatis.plugin.Intercepts;
/**
 * 
 * @author 79027
 * 插件签名,告诉mybatis插件用来拦截那个对象的那个方法
 */
@Intercepts({
    @Signature(type=ResultSetHandler.class,method="handleResultSets",args=Statement.class)
})
 
public class Myinterceptor1 implements Interceptor{
    //拦截目标对象
    public Object intercept(Invocation invocation) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("拦截的对象是1:"+invocation.getTarget());
        System.out.println("拦截方法是1:"+invocation.getMethod().toString());
        System.out.println("拦截参数是1:"+invocation.getArgs().length);
        //执行拦截对象真正的方法
        Object o=invocation.proceed();
        return o;
    }
    //包装目标对象 为目标对象创建动态代理
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        System.out.println("插件方法1--将要包装的目标对象1:"+target);
        //为当前对象创建代理对象
        Object o=Plugin.wrap(target, this);
        return o;
    }
    //获取插件初始化参数
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
        String value1=(String) properties.get("shuxing1");    
        String value2=(String) properties.get("shuxing2");
        System.out.println("插件初始化参数1:"+value1+":"+value2);
    }
 
}
拦截器2代码如下:

package com.thit.interceptor;
 
import java.sql.Statement;
import java.util.Properties;
 
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
 
 
import org.apache.ibatis.plugin.Intercepts;
/**
 * 
 * @author 79027
 * 插件签名,告诉mybatis插件用来拦截那个对象的那个方法
 */
@Intercepts({
    @Signature(type=ResultSetHandler.class,method="handleResultSets",args=Statement.class)
})
 
public class Myinterceptor2 implements Interceptor{
    //拦截目标对象 多个插件的时候按照    从后到前的顺序执行
    public Object intercept(Invocation invocation) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("拦截的对象是2:"+invocation.getTarget());
        System.out.println("拦截方法是2:"+invocation.getMethod().toString());
        System.out.println("拦截参数是2:"+invocation.getArgs().length);
        //执行拦截对象真正的方法
        Object o=invocation.proceed();
        return o;
    }
    //包装目标对象 为目标对象创建动态代理 按照从前到后的顺序执行
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        System.out.println("插件方法2--将要包装的目标对象2:"+target);
        //为当前对象创建代理对象
        Object o=Plugin.wrap(target, this);
        return o;
    }
    //获取插件初始化参数
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
        String value1=(String) properties.get("shuxing1");    
        String value2=(String) properties.get("shuxing2");
        System.out.println("插件初始化参数2:"+value1+":"+value2);
    }
 
}
最后测试代码如下:
        void getAllpersion1() {
            System.out.println("--------查询全部---------");
            SqlSession sqlSession = dbtools.getSession();
            PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);
            //分页
            //第二种,Mapper接口方式的调用,推荐这种使用方式。
             Page<Object> page=PageHelper.startPage(1, 10);
              System.out.println("当前页码:"+page.getPageNum());
                System.out.println("总记录数:"+page.getTotal());
                System.out.println("每页的记录数:"+page.getPageSize());
                System.out.println("总页码:"+page.getPages());
            
            List<Person> list=personMapper.getAllPersons();
            System.out.println("集合长度:"+list.size());
            PageInfo pageinfo=new PageInfo(list);
            
            System.out.println("pageinfo总条数:"+pageinfo.getTotal());
            System.out.println("pageinfo每页的记录数:"+pageinfo.getPageSize());
            System.out.println("pageinfo总页码:"+pageinfo.getPageNum());
            System.out.println("pageinfo总页码:"+pageinfo.getPages());
            
            for(Person p:list) {
                System.out.println(p);
            }
            System.out.println("---------结束---------");
    
        }
        
        
通过测试代码的输出结果,我么可以看到

插件初始化参数1:value1:value11
插件初始化参数2:value2:value22


插件方法1--将要包装的目标对象1:org.apache.ibatis.executor.CachingExecutor@6f7fd0e6
插件方法2--将要包装的目标对象2:org.apache.ibatis.executor.CachingExecutor@6f7fd0e6
当前页码:1
总记录数:0
每页的记录数:10
总页码:0

插件方法1--将要包装的目标对象1:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@72967906
插件方法2--将要包装的目标对象2:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@72967906
插件方法1--将要包装的目标对象1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
插件方法2--将要包装的目标对象2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
插件方法1--将要包装的目标对象1:org.apache.ibatis.executor.statement.RoutingStatementHandler@7d8995e
插件方法2--将要包装的目标对象2:org.apache.ibatis.executor.statement.RoutingStatementHandler@7d8995e


拦截的对象是2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
拦截方法是2:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
拦截参数是2:1

拦截的对象是1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
拦截方法是1:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
拦截参数是1:1

插件方法1--将要包装的目标对象1:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@5b12b668
插件方法2--将要包装的目标对象2:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@5b12b668
插件方法1--将要包装的目标对象1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
插件方法2--将要包装的目标对象2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
插件方法1--将要包装的目标对象1:org.apache.ibatis.executor.statement.RoutingStatementHandler@4c12331b
插件方法2--将要包装的目标对象2:org.apache.ibatis.executor.statement.RoutingStatementHandler@4c12331b

拦截的对象是2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
拦截方法是2:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
拦截参数是2:1

拦截的对象是1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
拦截方法是1:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
拦截参数是1:1

集合长度:10
pageinfo总条数:144
pageinfo每页的记录数:10
pageinfo总页码:1
pageinfo总页码:15
Person [id=1, username=tom, [email protected], gender=F, dept=null]
Person [id=2, username=tom, [email protected], gender=F, dept=null]
Person [id=3, username=tom, [email protected], gender=F, dept=null]
Person [id=4, username=tom, [email protected], gender=F, dept=null]
Person [id=5, username=tom, [email protected], gender=F, dept=null]
Person [id=6, username=tom, [email protected], gender=F, dept=null]
Person [id=7, username=tom, [email protected], gender=F, dept=null]
Person [id=8, username=tom, [email protected], gender=F, dept=null]
Person [id=9, username=tom, [email protected], gender=F, dept=null]
Person [id=10, username=tom, [email protected], gender=F, dept=null]
---------结束---------
--------------------- 
作者:浅水壁虎 
来源:CSDN 
原文:https://blog.csdn.net/huyiju/article/details/82454735 
版权声明:本文为博主原创文章,转载请附上博文链接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章