前言
大多数框架都支持插件,用户可通过编写插件来自行扩展功能,Mybatis也不例外。
在Mybatis中最出名的就是PageHelper 分页插件,下面我们先来使用一下这个分页插件。
如何集成分页插件
Spring-Boot+Mybatis+PageHelper
引入pom依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
配置分页插件配置项
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
service接口代码
PageInfo selectUsersByName(int pageIndex, int pageSize);
service实现类代码
@Override
public PageInfo selectUsersByName(int pageIndex, int pageSize) {
PageHelper.startPage(pageIndex, pageSize);
List<User> users = userMapper.selectUsersByName(null);
return new PageInfo(users);
}
mapper代码
<select id="selectUsersByName" resultMap="User">
select * from m_user
<where>
<if test="userName != null and userName != ''">
`name` = #{userName}
</if>
</where>
</select>
List<User> selectUsersByName(@Param("userName") String userName);
controller代码
@GetMapping("/user/name")
public PageInfo selectUsersByName(int pageIndex, int pageSize) {
return userService.selectUsersByName(pageIndex, pageSize);
}
然后我们访问
http://localhost:9002/user/name?pageIndex=1&pageSize=10
输出结果:
输出重要项说明:
-
pageNum:当前页码。 -
pageSize:每页数。 -
list:就是我们返回的业务数据。 -
total:总数据。 -
hasNextPage:是否存在下一页。
我们在看看输出SQL:
发现其实执行了两条SQL
:count和limit。
猜测分页插件实现
1.这个分页插件无非就是在我们的查询条件上拼接了个limit和做了一个count查询。
2.我们这里使用的是Mysql作为数据库,如果是Oracle的话那就不是limit了,所以这里有多重数据库对应的方案。
3.拦截并做了sql和相关处理。
根据官网快速入门插件
下面是来自官网的一段话:
MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) ParameterHandler (getParameterObject, setParameters) ResultSetHandler (handleResultSets, handleOutputParameters) StatementHandler (prepare, parameterize, batch, update, query) 这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看 MyBatis 发行包中的源代码。如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。因为在试图修改或重写已有方法的行为时,很可能会破坏 MyBatis 的核心模块。这些都是更底层的类和方法,所以使用插件的时候要特别当心。
通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。
那我们就尝试着按照官方来写一个插件。
自定义插件
@Intercepts({@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class TianPlugin implements Interceptor {
private Properties properties = new Properties();
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("老田写的一个Mybatis插件--start");
Object returnObject = invocation.proceed();
System.out.println("老田写的一个Mybatis插件---end");
return returnObject;
}
}
然后把插件类注入到容器中。
这里的自定义完全是官网给出的案例。从自定义的插件类中看到有个update,我们猜测肯定是需要执行update才会被拦截到。
访问前面的代码:http://localhost:9002/updateUser
成功了。
这是大家肯定会联想到我们刚刚开始学动态代理的时候,不就是在要调用的方法的前面和后面做点小东东吗?
Mybatis
的插件确实就是这样的。
我们来分析一下官方的那段话和我们自定义的插件。
分析
首先,我们自定义的插件必须是针对下面这四个类以及方法。
-
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) -
ParameterHandler (getParameterObject, setParameters) -
ResultSetHandler (handleResultSets, handleOutputParameters) -
StatementHandler (prepare, parameterize, batch, update, query)
其次,我们必须实现Mybatis的Interceptor。
Interceptor中三个方法的作用:
-
intercept():执行拦截内容的地方,比如:在调用某类方法前后做一些自己的处理,简单就是打印日志。 -
plugin():决定是否触发intercept()方法。 -
setProperties():给自定义的拦截器传递我们配置的属性参数(这个可以暂时不管他,后面我们写一个相对完整点的插件,你就明白是干啥的了)。
标签:插件,自定义,pageSize,update,Mybatis,MyBatis,解析 From: https://www.cnblogs.com/grassLittle/p/17285214.html