Mybatis插件
简介:
Mybatis作为一个应用广泛的优秀的ORM开源框架,这个框架具有强大的灵活性,在四大组件(Executor,StatementHandler,ParameterHandler,ResultSetHandler)处提供了简单易用的插件扩展机制,Mybatis对持久曾的操作就是借助于四大核心对象,Mybatis支持用插件对四大核心对象进行拦截,对Mybatis来说,插件就是拦截器,用来增强核心对象的功能,增强功能本质上是借助于底层的动态代理实现的,换句话说,Mybatis中的四大对象都是代理对象;
Mybatis所允许拦截的方法如下:
-
执行器(Executor):update,query,commit,rollback等
-
SQL语法构建器(StatementHandler):perpare,parameterize,batch,update,query等
-
参数处理器(ParameterHandler):getParameterObject,setParameters等
-
结果集处理器(ResultSetHandler):handleResultSets,handleOutputParameters等
自定义插件
@Intercepts({
@Signature(type = StatementHandler.class,
method = "prepare",
args = {Connection.class,Integer.class})
})
public class Myplugin implements Interceptor {
?
/**
* 拦截方法:只要被拦截的目标对象的目标方法被执行时,每次都会执行Interceptor方法
* @param invocation
* @return
* @throws Throwable
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("对方法进行了增强!!");
return invocation.proceed();//原方法执行
}
?
/**
* 把当前的拦截器生成代理对象存到拦截器链中
* @param o
* @return
*/
@Override
public Object plugin(Object o) {
Object wrap = Plugin.wrap(o, this);
return wrap;
}
?
/**
* 获取配置文件参数
* @param properties
*/
@Override
public void setProperties(Properties properties) {
System.out.println("获取到的配置文件的参数是:" + properties);
}
}
按照顺序在sqlMapConfig.xml配置
@Test
public void test2() {
?
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();
?
IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class);
IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class);
IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class);
?
User user1 = mapper1.getUserById(1);
//清空一级缓存
sqlSession1.close();
?
User user = new User();
user.setId(1);
user.setUsername("Tom");
mapper3.updateUser(user);
sqlSession3.commit();
?
User user2 = mapper2.getUserById(1);
?
System.out.println(user1 == user2);
}
运行结果:
获取到的配置文件的参数是:{name=tom}
对方法进行了增强!!
对方法进行了增强!!
对方法进行了增强!!
false
结论,目标方法在执行sql语句的时候,plugin先执行,把当前的拦截器生成代理对象存到拦截器链中,意味这Myplugin生效,如果调用StatementHandler里面的prepare方法时,会进入Myplugin里面的intercept方法中来完成对该方法的增强,执行几次sql,intercept就会执行几次;
pageHelper插件
pom
com.github.pagehelper
pagehelper
3.7.5
com.github.jsqlparser
jsqlparser
0.9.1
sqlMapConfig.xml
@Test
public void pageHelperTest(){
PageHelper.startPage(1,1);
List users = mapper.getAllUser();
users.forEach(item -> {
System.out.println(item);
});
?
PageInfo pageInfo = new PageInfo<>(users);
System.out.println("总条数:" + pageInfo.getTotal());
System.out.println("总页数:" + pageInfo.getPages());
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("每页显示的条数:" + pageInfo.getPageSize());
?
}
运行结果:
User(id=1, username=Tom, orders=null, roles=null)
总条数:2
总页数:2
当前页:1
每页显示的条数:1
通用mapper
通用mapper就是为了解决单表CRUD,基于Mybatis的插件机制,开发人员不需要编写sql,不需要在DAO中增加方法,只要写好实体类,就能支持相应的CRUD;
pom
tk.mybatis
mapper
3.1.2
sqlMapConfig.xml
修改User实体
@Data
@Table(name = "user")//与数据表名对应
public class User implements Serializable {
?
@Id //表示主键id
@GeneratedValue(strategy = GenerationType.AUTO)//设置主键的生成策略
private Integer id;
?
@Column(name = "username")//与数据字段名对应
private String username;
}
mapper接口
public interface UserMapper extends Mapper {
?
}
@Test
public void mapperTest() throws IOException {
//1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2.解析了配置文件,并创建了sqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.生产sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(2);
?
User user1 = mapper.selectOne(user);
?
System.out.println(user1);
}
运行结果
User(id=2, username=Jerry)