官方文档:https://github.com/pagehelper/pagehelper-spring-boot
1、引入包,测试过以下版本兼容性还是比较好的
<!--Mybatis-SpringBoot集成-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!--mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.3-beta1</version>
</dependency>
2、配置插件,直接贴application.yml 文件内容:
spring:
datasource:
name: mydb
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.0.1:3306/mar?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
minIdle: 1
maxActive: 20
initialSize: 1
timeBetweenEvictionRunsMillis: 3000
minEvictableIdleTimeMillis: 300000
mybatis:
#mapper 的地址
mapperLocations: classpath*:mapper/*.xml
type-aliases-package: tk.mybatis.springboot.model
mapper:
not-empty: false
#数据库类型
identity: MYSQL
#分页插件配置
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
3、配置完成已经可以使用了:
//设置好分页信息
PageHelper.startPage(1, 2);
//查询用户列表
users = userService.listUser();
//用PageInfo对结果进行包装
page = new PageInfo(users);
4、至于listUser()这个方法的sql,什么都不用做,因为PageHelper采用的是拦截器方式实现的分页:
<select id="listUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
</select>
5、Demo下载地址:https://download.csdn.net/download/the_fool_/10958436
6、SSM框架的配置:
7、实现原理:
8、高效分页demo(转载,版本要5.0.0):https://blog.csdn.net/weixin_36666151/article/details/80471767
摘抄了部分关键代码,主要是对单表查询,多表查询原作者没写, 但是还是有一定的参考价值的:
接下来我们来修改mybatis分页插件的拼接limit语句的逻辑代码,方法非常简单,新建一个这样的类,下面的的代码全部不要改,包名,类名都不能改。其目的就是利用Java类加载机制,替代其原来jar包里面有的这个对象,因为这个对象已经存在了,Java就不会再去加载其原来插件里面的这个对象了,从而巧妙的修改了其源码。
package com.github.pagehelper.dialect.helper;
import org.apache.ibatis.cache.CacheKey;
import com.github.pagehelper.Page;
import com.github.pagehelper.dialect.AbstractHelperDialect;
public class MySqlDialect extends AbstractHelperDialect {
@Override
public String getPageSql(String sql, Page page, CacheKey pageKey) {
StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14);
sql= sql.toLowerCase();//全部转换成小写形式
if (page.getStartRow() == 0) {
sqlBuilder.append(sql);
sqlBuilder.append(" LIMIT ");
sqlBuilder.append(page.getPageSize());
}
else if(page.getStartRow()>10000&&this.inSingletonTable(sql)){//判断是否是大页码并且单表查询
String[] tables = this.getTableName(sql);
String sql1 =sql.split(tables[0])[0];
sqlBuilder.append(sql1);
sqlBuilder.append(" (Select id as id2,(@rowNum:=@rowNum+1) as rowNo From ");
sqlBuilder.append(tables[0]);
sqlBuilder.append(",(Select (@rowNum :=0) ) b) r ,");
sqlBuilder.append(tables[0]);
sqlBuilder.append(" ");
sqlBuilder.append(tables[1]!=null?tables[1]:" ");
sqlBuilder.append(" where r.id2= ");
sqlBuilder.append(tables[1]!=null?tables[1]:tables[0]);
sqlBuilder.append(".id ");
sqlBuilder.append(" and r.rowNo> ");
sqlBuilder.append(page.getStartRow());
if (sql.contains("where")) {//拼接原来SQL语句中的where语句后面的语句
sqlBuilder.append(" and ");
sqlBuilder.append(sql.split("where")[1]);
}else {
//拼接原有的SQL表名后面的一段后面
if (tables[1]!=null) {//表有别名
String[] sql2 =sql.split(tables[1]);
sqlBuilder.append(" ");
sqlBuilder.append(sql2.length>1?sql2[1]:" ");
}else {
String[] sql2 =sql.split(tables[0]);
sqlBuilder.append(" ");
sqlBuilder.append(sql2.length>1?sql2[1]:" ");
}
}
sqlBuilder.append(" LIMIT ");
sqlBuilder.append(page.getPageSize());
}else{
sqlBuilder.append(sql);
sqlBuilder.append(" LIMIT ");
sqlBuilder.append(page.getStartRow());
sqlBuilder.append(",");
sqlBuilder.append(page.getPageSize());
pageKey.update(page.getStartRow());
}
pageKey.update(page.getPageSize());
return sqlBuilder.toString();
}
private boolean inSingletonTable(String sql) {
if (sql.contains("join")||sql.contains("JOIN")) {
return false;
}
if (sql.contains("where")) {
if (sql.contains("from")) {
String tables= sql.split("from")[1].split("where")[0];
if (tables.contains(",")) {
return false;
}
}
}
return true;
}
private String[] getTableName(String sql) {
String[] tables = new String[2];
if (sql.contains("where")) {
String tablenames = sql.split("from")[1].split("where")[0];
tablenames = this.removekg(tablenames);//删除表名前后的空格
if (tablenames.contains(" ")) {
tables=tablenames.split(" ");
return tables;
}else {
tables[0]=tablenames;
return tables;
}
} else if (sql.contains("group")&&!sql.contains("order")) {
String tablenames = sql.split("from")[1].split("group")[0];
tablenames = this.removekg(tablenames);//删除表名前后的空格
if (tablenames.contains(" ")) {
tables=tablenames.split(" ");
return tables;
}else {
tables[0]=tablenames;
return tables;
}
} else if (sql.contains("order")&&!sql.contains("group")) {
String tablenames = sql.split("from")[1].split("order")[0];
tablenames = this.removekg(tablenames);//删除表名前后的空格
if (tablenames.contains(" ")) {
tables=tablenames.split(" ");
return tables;
}else {
tables[0]=tablenames;
return tables;
}
} else if (sql.contains("order")&&sql.contains("group")) {
int orderIndex =sql.indexOf("order");
int groupIndex =sql.indexOf("group");
if (orderIndex<groupIndex) {
String tablenames = sql.split("from")[1].split("order")[0];
tablenames = this.removekg(tablenames);//删除表名前后的空格
if (tablenames.contains(" ")) {
tables=tablenames.split(" ");
return tables;
}else {
tables[0]=tablenames;
return tables;
}
}else {
String tablenames = sql.split("from")[1].split("group")[0];
tablenames = this.removekg(tablenames);//删除表名前后的空格
if (tablenames.contains(" ")) {
tables=tablenames.split(" ");
return tables;
}else {
tables[0]=tablenames;
return tables;
}
}
}else if (!sql.contains("where")&&!sql.contains("order")&&!sql.contains("group")) {
String tablenames = sql.split("from")[1];
tablenames = this.removekg(tablenames);//删除表名前后的空格
if (tablenames.contains(" ")) {
tables=tablenames.split(" ");
return tables;
}else {
tables[0]=tablenames;
return tables;
}
}
return tables;
}
//删除字符串两头的空格
private String removekg(String textContent) {
textContent = textContent.trim();
while (textContent.startsWith(" ")) {//这里判断是不是全角空格
textContent = textContent.substring(1, textContent.length()).trim();
}
while (textContent.endsWith(" ")) {
textContent = textContent.substring(0, textContent.length() - 1).trim();
}
return textContent;
}
}