目录
1说明
1、 1;
2自定义一个插件
2、 1创建一个java文件;
2、 2说明下这个自定义的插件类;
2、 2.1自定义插件类,必须实现Interceptor接口;
2、 2.2;
2、 2.3;
2、 2.4;
2、 2.5;
2、 2注册这个自定义的插件类;
2、 3测试;
2、 4效果;
3自定义多个插件时,该如何执行呢
3、 1定义第二个插件类;
3、 2注册两个插件类方式;
3、 3执行效果;
4使用一个强大的分页插件
4、 1下载插件;
4、 1.1百度搜索PageHelper;
4、 1.2可以选择中文文档;
4、 1.3下jar包;
4、 2引入jar包;
4、 3只是在Junit中使用方式变了而已,其他地方都不变;
4、 4mybatis中还需要引入该插件;
4、 5效果;
1说明
1.1
本文内容整合 http://www.gulixueyuan.com/my/course/43任务79至任务83的内容
1、 2;
本文代码基于HellWorld代码
2自定义一个插件
2.1创建一个java文件
package com.atguigu.mybatis.dao;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
/**
* 完成插件签名:
* 告诉MyBatis当前插件用来拦截哪个对象的哪个方法
*/
@Intercepts(
{
@Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
})
public class MyFirstPlugin implements Interceptor{
/**
* intercept:拦截:
* 拦截目标对象的目标方法的执行;
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
// TODO Auto-generated method stub
System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());
//动态的改变一下sql运行的参数:以前1号员工,实际从数据库查询3号员工
Object target = invocation.getTarget();
System.out.println("当前拦截到的对象:"+target);
//拿到:StatementHandler==>ParameterHandler===>parameterObject
//拿到target的元数据
MetaObject metaObject = SystemMetaObject.forObject(target);
Object value = metaObject.getValue("parameterHandler.parameterObject");
System.out.println("sql语句用的参数是:"+value);
//修改完sql语句要用的参数
metaObject.setValue("parameterHandler.parameterObject", 11);
//执行目标方法
Object proceed = invocation.proceed();
//返回执行后的返回值
return proceed;
}
/**
* plugin:
* 包装目标对象的:包装:为目标对象创建一个代理对象
*/
@Override
public Object plugin(Object target) {
// TODO Auto-generated method stub
//我们可以借助Plugin的wrap方法来使用当前Interceptor包装我们目标对象
System.out.println("MyFirstPlugin...plugin:mybatis将要包装的对象"+target);
Object wrap = Plugin.wrap(target, this);
//返回为当前target创建的动态代理
return wrap;
}
/**
* setProperties:
* 将插件注册时 的property属性设置进来
*/
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
System.out.println("插件配置的信息:"+properties);
}
}
2.2说明下这个自定义的插件类
2.2.1自定义插件类,必须实现Interceptor接口
2.2.2
plugin方法,会比intercept方法先执行。因为plugin方法是得到一个动态代理对象,在执行这个动态代理对象指定的方法时才会执行intercept方法
2.2.3
必须有Intercepts注解
type:指定要拦截的哪个对象(mybatis四大对象都可以被拦截到)
method:指定要拦截到对象的方法名
args:指定了对象的方法名还不够,还需要精确到入参。(防止类加载的情况发生
2.2.4
这个拦截器的功能是:
改变一下sql运行的参数:无论想查询处几号员工,实际从数据库都查询的是11号员工。
@Override
public Object intercept(Invocation invocation) throws Throwable {
// TODO Auto-generated method stub
System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());
//动态的改变一下sql运行的参数:以前1号员工,实际从数据库查询3号员工
Object target = invocation.getTarget();
System.out.println("当前拦截到的对象:"+target);
//拿到:StatementHandler==>ParameterHandler===>parameterObject
//拿到target的元数据
MetaObject metaObject = SystemMetaObject.forObject(target);
Object value = metaObject.getValue("parameterHandler.parameterObject");
System.out.println("sql语句用的参数是:"+value);
//修改完sql语句要用的参数
metaObject.setValue("parameterHandler.parameterObject", 11);
//执行目标方法
Object proceed = invocation.proceed();
//返回执行后的返回值
return proceed;
}
2.2.5
剩下的说明,可以看下该插件类中的注释
2.2注册这个自定义的插件类
下面的plugins就是注释插件的。property就是设置属性值的
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--plugins:注册插件 -->
<plugins>
<plugin interceptor="com.atguigu.mybatis.dao.MyFirstPlugin">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 -->
<mappers>
<mapper resource="EmployeeMapper.xml" />
</mappers>
</configuration>
2.3测试
@Test
public void test01() throws IOException {
// 1、获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
// 2、获取sqlSession对象
SqlSession openSession = sqlSessionFactory.openSession();
try {
// 3、获取接口的实现类对象
//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmpById(1);
System.out.println(mapper);
System.out.println(employee);
} finally {
openSession.close();
}
}
2.4效果
3自定义多个插件时,该如何执行呢
3.1定义第二个插件类
package com.atguigu.mybatis.dao;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
@Intercepts(
{
@Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
})
public class MySecondPlugin implements Interceptor{
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("MySecondPlugin...intercept:"+invocation.getMethod());
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
// TODO Auto-generated method stub
System.out.println("MySecondPlugin...plugin:"+target);
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
}
}
3.2注册两个插件类方式
<!--plugins:注册插件 -->
<plugins>
<plugin interceptor="com.atguigu.mybatis.dao.MyFirstPlugin">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</plugin>
<plugin interceptor="com.atguigu.mybatis.dao.MySecondPlugin"></plugin>
</plugins>
说明:如果两个自定义的插件类都同时拦截同一个对象的里的同一方法。这里的编写顺序就决定了先创建代理对象的先后顺序。这里表示先创建com.atguigu.mybatis.dao.MyFirstPlugin的代理对象,根据源码可知会把这个代理对象在创建一次变成com.atguigu.mybatis.dao.MySecondPlugin的代理对象。
即就是:创建动态代理的时候,是按照插件配置顺序创建层层代理对象。 执行目标方法的之后,按照逆向顺序执行
3.3执行效果
4使用一个强大的分页插件
说明代码还是基于HellWorld代码
4.1下载插件
这个插件是mybatis的非常强大的分页插件
4.1.1百度搜索PageHelper
4.1.2可以选择中文文档
4.1.3下jar包
4.2引入jar包
4.3只是在Junit中使用方式变了而已,其他地方都不变
改代码中的info与page对象都可以打印出分页的详细信息。具体操作可参考
http://www.gulixueyuan.com/course/43/task/1232/show的任务83:MyBatis_扩展_分页_PageHelpler分页插件使用
@Test
public void test01() throws IOException {
// 1、获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
// 2、获取sqlSession对象
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Page<Object> page = PageHelper.startPage(5, 1);
List<Employee> emps = mapper.getEmps();
//传入要连续显示多少页
PageInfo<Employee> info = new PageInfo(emps, 5);
for (Employee employee : emps) {
System.out.println(employee);
}
System.out.println("当前页码:"+page.getPageNum());
System.out.println("总记录数:"+page.getTotal());
System.out.println("每页的记录数:"+page.getPageSize());
System.out.println("总页码:"+page.getPages());
///xxx
System.out.println("当前页码:"+info.getPageNum());
System.out.println("总记录数:"+info.getTotal());
System.out.println("每页的记录数:"+info.getPageSize());
System.out.println("总页码:"+info.getPages());
System.out.println("是否第一页:"+info.isIsFirstPage());
System.out.println("连续显示的页码:");
int[] nums = info.getNavigatepageNums();
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
//xxxx
} finally {
openSession.close();
}
}
4.4mybatis中还需要引入该插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
4.5效果
版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: