专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 MyBatis分页插件原理

MyBatis分页插件原理

更新时间:2022-10-08 09:53:23 来源:赢咖4 浏览987次

插件介绍

Mybatis 作为一个被广泛使用的 ORM 开源框架,具有很大的灵活性,在四个组件(Excutor、StatementHandler、ParameterHandler、ResultHandler)处理简单易用的插件扩展机制,Mybatis 对 Long 层的操作是借助四个核心对象。Mybatis支持用插件拦截四个核心对象,是Mybatis插入一个就是拦截器,增强核心对象的功能,增强本质上是借助底层动态代理来实现的, 也就是说,Mybatis 中的四个对象都是代理对象

Mybatis 允许的拦截方式如下:

 actuator Executor(update、query、commit、rollback Other methods );
Parameter processor ParameterHandler(getParameterObject、setParameters Method );
Result set processor ResultSetHandler(handleResultSets、handleOutputParameters Other methods );
SQL Syntax builder StatementHandler(prepare、parameterize、batch、update、query Other methods );

原理

当四个对象被创建时,

 1. Each created object is not returned directly , It is interceptorChain.pluginAll(parameterHandler);
2. All that you get interceptor( Interceptor ){ The interface that the plug-in needs to implement }; call interceptor.plugin(target);
return target Packed object ;
3. Plug-in mechanism , We can use the plug-in as the target object ;AOP( Face to face ) Our plug-in can create proxy objects for four objects
, The proxy object can intercept each execution of the four objects ;

简单拦截 Executor 的具体实现类获取代码:

 public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? this.defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Object executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (this.cacheEnabled) {
 // Second level cache Executor
executor = new CachingExecutor((Executor)executor);
}
// Every Executor example , Will be passed by interceptorChain To deal with 
Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
return executor;
}
 In the actual development process , We use it a lot Mybaits Plugins are paging plugins ,
Through the paging plug-in, we can write without count Statement and limit Of In this case, you can get paging
Later data , It brings us great convenience in development . Except paging , Plug in usage scenarios mainly include
Update the common fields of the database , Sub database and sub table , Encryption and decryption, etc .

自定义插件

1.Mybatis插件接口-interceptor

intercept 方法,

插件插件方法的核心方法,生成

setProperties 方法的目标 Proxy 对象,传递插件所需的参数

2.自定义插件

设计并实现一个自定义插件:

package com.lg.plugin;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import java.sql.Connection;
import java.util.Properties;
@Intercepts({
 // Notice the curly braces , In other words, there can be more @Signature Intercept multiple places , All use this interceptor 
@Signature(type = StatementHandler.class, // Which class to intercept 
method = "prepare", // Which method to intercept 
args = {
Connection.class,Integer.class}) // To avoid intercepting overloaded methods , Pass in interception parameters , The input parameter must be consistent with the input parameter type of the interception method 
})
public class MyPlugin implements Interceptor {
// As can be seen from the above principles , When the target method of the target object is executed , Every time I do intercept Method 
public Object intercept(Invocation invocation) throws Throwable {
System.out.println(" Enhance the method ...");
return invocation.proceed();
}
// The target class object that will be intercepted , As the reference , Incoming interceptors , The interceptor acts as a proxy , Generate proxy objects 
/** * Packaging target object , Create a proxy object for the target object * @param target For intercepted objects * @return Proxy object */
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
// Get the properties of the configuration file 
// When the plug-in is initialized, call , It's only called once , The properties of plug-in configuration come in from here 
public void setProperties(Properties properties) {
System.out.println(" The parameter received is ==>" + properties);
}
}

Mybatis插件机制-pageHelper

开发步骤:

导入通用 PageHelper 坐标

在核心配置文件PageHelper插件中配置mybatis

测试寻呼数据采集

1.导入通用PageHelper坐标

 <!-- Paging assistant -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>

2.核心配置文件PageHelper插件中的mabatis配置

<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>

3.测试分页代码实现

 // Test paging 
@Test
public void testPage(){
PageHelper.startPage(1,3);
StuDao mapper = sqlSession.getMapper(StuDao.class);
List<Stu> stus = mapper.selectList();
for (Stu stu:
stus) {
System.out.println(stu.toString());
}
PageInfo<Stu> stuPageInfo = new PageInfo(stus);
System.out.println(" Total page number ==>" + stuPageInfo.getPages());
System.out.println(" Total number of articles ==>" + stuPageInfo.getTotal());
System.out.println(" The current page ==>" + stuPageInfo.getPageNum());
}

结果 :

Mybatis Universal 插件 Mapper

什么是通用映射器?

Universal Mapper 这个是为了解决单表的增删改查问题,基于Mybatis的插件机制,开发者不用写sql,也不需要DAO里面的Add方法,直接写实体类,可以支持相应的增删改查方法

如何使用 ?

1.导入通用映射器依赖

 <!-- Universal Mapper-->
<!-- https://mvnrepository.com/artifact/tk.mybatis/mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.4.5</version>
</dependency>

2.在核心配置文件mapper插件中的mabatis配置

<plugin interceptor="tk.mybatis.mapper.mapperhelper.MapperInterceptor">
<!-- Specifies the current generic mapper Which interface is used -->
<property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
</plugin>

3.设置实体类的主键,设置表名

package com.lg.pojo;
import javax.persistence.*;
/** * Student information sheet */
@Table(name = "Stu") // Map a table 
public class Stu {
@Override
public String toString() {
return "Stu{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", gender='" + gender + '\'' +
", phone='" + phone + '\'' +
", hobby='" + hobby + '\'' +
", info='" + info + '\'' +
'}';
}
@Id // Corresponding to the annotation id
@GeneratedValue(strategy = GenerationType.IDENTITY) // mysql yes IDENTITY Self increasing ,Oracle yes SEQUENCE Sequence 
private int sid;
@Column(name = "sname") // Consistent names , No need to write 
private String sname;
private String gender;
private String phone;
private String hobby;
private String info;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}

4.定义是通用的Mapper

// Just inherited Mapper Interface can 
public interface StuMapper_Plugin extends Mapper<Stu> {
}

测试班:

// Test common Mapper plug-in unit 
@Test
public void testMapper(){
StuMapper_Plugin mapper = sqlSession.getMapper(StuMapper_Plugin.class);
Stu stu = new Stu();
stu.setSid(313);
Stu stu1 = mapper.selectOne(stu);
System.out.println(stu1.toString());
// 2. Example Method 
Example example = new Example(Stu.class);
example.createCriteria().andEqualTo("sid",313);
mapper.selectByExample(example);
}

 

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>