一、参照了PageHelper的源码,不是为了重复造轮子,只是为了能让自己有造轮子的水平。
二、准备:数据库 test,数据表:
insert into student(name,age) values('paul',33);
insert into student(name,age) values('david',23);
insert into student(name,age) values('kate',23);
insert into student(name,age) values('cindy',21);
insert into student(name,age) values('hilary',17);
insert into student(name,age) values('clinton',25);
insert into student(name,age) values('trump',34);
insert into student(name,age) values('yoke',21);
insert into student(name,age) values('owen',12);
insert into student(name,age) values('karick',29);
insert into student(name,age) values('tomas',35);
insert into student(name,age) values('muller',41);
三、创建spring boot项目,引入相关依赖,完整pom如下,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.edu.tju</groupId>
<artifactId>my-pager</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
四、配置application.properties
server.port=8030
spring.datasource.url=jdbc:mysql://xxx.xxx.xxx.xxx/test
spring.datasource.username=root
spring.datasource.password=xxxxxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.configuration.map-underscore-to-camel-case=true
五、定义用来分页类、分页辅助类、拦截器类、拦截器配置类
package cn.edu.tju.config;
public class Pager {
int pageNumber;
int pageSize;
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
}
package cn.edu.tju.config;
public class MyPageHelper {
protected static ThreadLocal<Pager> myPager=new ThreadLocal<>();
public static void startPage(int pageNumber,int pageSize){
Pager pager=new Pager();
pager.setPageNumber(pageNumber);
pager.setPageSize(pageSize);
myPager.set(pager);
}
public static Pager getLocalPage(){
return myPager.get();
}
public static void removeLocalPage(){
myPager.remove();
}
}
package cn.edu.tju.config;
import cn.edu.tju.config.MyPageHelper;
import cn.edu.tju.config.Pager;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import java.sql.Connection;
import java.util.Properties;
@Intercepts({@Signature(type = StatementHandler.class,method = "prepare",args={Connection.class,Integer.class})})
public class MyInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
//打印这句,说明拦截器起作用了
System.out.println("my interceptor was called......");
//通过invocation对象拿到StatementHandler对象
StatementHandler statementHandler=(StatementHandler)invocation.getTarget();
MetaObject metaObject= SystemMetaObject.forObject(statementHandler);
MappedStatement mappedStatement=(MappedStatement)metaObject.getValue("delegate.mappedStatement");
//拿到Mapper中的方法名 ,例如: cn.edu.tju.mapper.StudentMapper.getStudentList
String id = mappedStatement.getId();
//拿到要执行的SQL 语句, 例如:select * from student
BoundSql boundSql = statementHandler.getBoundSql();
String sql = boundSql.getSql();
//从ThreadLocal中拿到pageNumber和pageSize
Pager localPage = MyPageHelper.getLocalPage();
int pageSize=localPage.getPageSize();
int pageNumber=localPage.getPageNumber();
//判断是否需要分页
if(pageNumber>0 && pageSize>0 && sql.contains("select")){
//计算SQL语句中需要添加的分页信息,例如: limit 2,10,并将其添加到sql 语句中
String startPosition=String.valueOf((pageNumber-1)*pageSize);
String count=String.valueOf(pageSize);
String pageSql=sql+ " limit ";
pageSql+= startPosition;
pageSql+=",";
pageSql+=count;
//修改sql语句用来完成分页
metaObject.setValue("delegate.boundSql.sql",pageSql);
//清除分页信息
MyPageHelper.removeLocalPage();
}
//执行SQL语句
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
@Override
public void setProperties(Properties properties) {
}
}
package cn.edu.tju.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MyConfig {
@Bean
public MyInterceptor getInterceptor(){
return new MyInterceptor();
}
}
六、定义实体类、mapper类、controller类
package cn.edu.tju.domain;
public class Student {
private int id;
private String name;
private String age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
package cn.edu.tju.mapper;
import cn.edu.tju.domain.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface StudentMapper {
@Select("select * from student")
List<Student> getStudentList();
}
package cn.edu.tju.controller;
import cn.edu.tju.config.MyPageHelper;
import cn.edu.tju.domain.Student;
import cn.edu.tju.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class StudentController {
@Autowired
private StudentMapper studentMapper;
@RequestMapping("/getStudentByPage/{pageNumber}/{pageSize}")
public List<Student> getStudentByPage(@PathVariable("pageNumber") int pageNumber,
@PathVariable("pageSize")int pageSize){
//开始分页
MyPageHelper.startPage(pageNumber,pageSize);
return studentMapper.getStudentList();
}
}
七、定义启动类,并启动程序:
package cn.edu.tju;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class,args);
}
}
八、运行结果: