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=tom@imooc.com, gender=F, dept=null]
Person [id=2, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=3, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=4, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=5, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=6, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=7, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=8, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=9, username=tom, email=tom@imooc.com, gender=F, dept=null]
Person [id=10, username=tom, email=tom@imooc.com, gender=F, dept=null]
---------结束---------
---------------------
作者:浅水壁虎
来源:CSDN
原文:https://blog.csdn.net/huyiju/article/details/82454735
版权声明:本文为博主原创文章,转载请附上博文链接!