limit n,m 从第n个开始,往后取m个(注 不包括第n个数据)OFFSET n ROWS FETCH NEXT m ROWS ONLY 从第n行开始,往后取m行(注 不包括第n行数据)先说结论:
mysql写法:
SELECT * FROM user2
LIMIT (#{pageNum} - 1) * #{pageSize}, #{pageSize}oracle写法:
SELECT * FROM user2
OFFSET (#{pageNum} - 1) * #{pageSize} ROWS FETCH NEXT #{pageSize} ROWS ONLY
直接看代码:
@Mapper
public interface PageTestDao {// 查数据// start:从第几条开始,向后要数据// pageSize:一页多少条数据List getUserInfoByParams(@Param("nameParam") String name,@Param("start") int start,@Param("pageSize") int pageSize);// 返回总条数int getCountByParams(@Param("nameParam") String name);
}
name like CONCAT('%', #{nameParam}, '%')
@Service
@RequiredArgsConstructor
public class PageTestService {private final PageTestDao pageTestDao;public PageResponse getPageTest(UserRequest userRequest) {final List userEntityList = pageTestDao.getUserInfoByParams(userRequest.getNameParam(),userRequest.getStart(), userRequest.getPageSize());final int total = pageTestDao.getCountByParams(userRequest.getNameParam());return new PageResponse<>(userEntityList, total);}
}
// 若分页的需求很多,可把分页相关的参数抽出来
@Data
public class PageRequest {// 第几页private int pageNum;// 每页几行数据private int pageSize;// 计算从第几行开始// 无论是limit、还是fetch 都是从某一行数据开始,向后取 pageSize 条数据public int getStart() {if (pageNum <= 0) {return 0;}return (pageNum - 1) * pageSize;}
}// 入参
@EqualsAndHashCode(callSuper = true)
@Data
public class UserRequest extends PageRequest {// 搜索参数private String nameParam;
}// 返回实体类,因为分页需要返回总条数,前端好做下标第几页
@Data
@AllArgsConstructor
public class PageResponse {private List data;// 总条数private int total;
} @RestController
@RequiredArgsConstructor
public class PageTestController {private final PageTestService pageTestService;@PostMapping("/page-test")public PageResponse getPageTest(@RequestBody UserRequest userRequest){return pageTestService.getPageTest(userRequest);}
}

先看一下List的截取
// 从第几个下标,到第几个下标
List subList(int fromIndex, int toIndex);
public void test_ListSub() {// 创建模拟数据,字符串 0-9的集合final List list = IntStream.range(0, 10).mapToObj(i -> i + "").collect(Collectors.toList());System.out.println(list);// 截取从下标0到5的数据System.out.println(list.subList(0, 5));// 截取从下标3到5的数据System.out.println(list.subList(3, 5));}

回归上述分页例子,代码改成如下:
dao层 不加 limit 条件
SELECT * FROM user2name like CONCAT('%', #{nameParam}, '%')
server层:
public PageResponse getPageTestByListSub(UserRequest userRequest) {final List allData = pageTestDao.getUserInfoByParamsNoLimit(userRequest.getNameParam());// 下标开始final int start = userRequest.getStart();// 下标结束final int end = start + userRequest.getPageSize();// 截取数据final List userEntityList = allData.subList(start, end);final int total = pageTestDao.getCountByParams(userRequest.getNameParam());return new PageResponse<>(userEntityList, total);}
其实PageHelper官网中有详细的文档以及例子:https://pagehelper.github.io/docs/howtouse/
下面例子只是讲其与springboot结合的核心内容,即快速开发:
引入相关jar包坐标到pom.xml中
com.github.pagehelper pagehelper-spring-boot-starter 1.3.0
dao层的sql不需要加 Limit 条件(因为PageHelper会自动帮忙加的)
SELECT * FROM user2name like CONCAT('%', #{nameParam}, '%')
service层修改如下:
public PageInfo getPageTest(UserRequest userRequest) {// 告诉PageHelper数据要从第几页,每页多少条数据// 注:一定要在select查询语句之前使用该方法,否则无效PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize());// 查询sqlfinal List userEntityList = pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam());// 返回dto,使用插件自带的PageInforeturn new PageInfo<>(userEntityList);// 上述逻辑还可以简写为:// return PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize())// .doSelectPageInfo(() -> pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam()));} 结果如下(与之前查询结果一致,没问题):
{"total": 9,"list": [{"name": "4a","pwd": "D"},{"name": "5a","pwd": "E"},{"name": "6a","pwd": "F"}],"pageNum": 2,"pageSize": 3,"size": 3,"startRow": 4,"endRow": 6,"pages": 3,"prePage": 1,"nextPage": 3,"isFirstPage": false,"isLastPage": false,"hasPreviousPage": true,"hasNextPage": true,"navigatePages": 8,"navigatepageNums": [1,2,3],"navigateFirstPage": 1,"navigateLastPage": 3
}
为什么说该插件很优秀呢,查看PageInfo的返回参数,核心内容:
// 当前页private int pageNum;// 每页的数量private int pageSize;// 当前页的数量private int size;// 总记录数private long total;// 总页数private int pages;// 结果集private List list;// 以下内容都是其自动帮生成的// 对于前端来说极其友好,前端分页功能的全部参数都包含了// 前一页的页码private int prePage;// 下一页的页码private int nextPage;// 是否为第一页private boolean isFirstPage = false;// 是否为最后一页private boolean isLastPage = false;// 是否有前一页private boolean hasPreviousPage = false;// 是否有下一页private boolean hasNextPage = false;// 导航条上的第一页的页码private int navigateFirstPage;// 导航条上的第一页的页码private int navigateLastPage;
查看PageHelper执行了什么sql语句
