一、分页技术的核心条件
二、代码实现
2.1 分页数据封装类PageEntity
1.初始化当前页数
2.初始化每页显示条数
3.计算limit中起始下标索引值
package cn.kooun.common.page;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 通用分页参数封装
* @author HuangJingNa
* @date 2019年12月23日 下午3:17:14
*
*/
@Getter
@Setter
@ToString
public class PageEntity {
/**当前页数*/
private Integer currentPage;
/**分页数据*/
private List<?> dataPage;
/**总记录数*/
private Integer total;
/**每页显示的条数*/
private Integer countPage;
public PageEntity(Integer currentPage) {
this.currentPage = currentPage;
this.initCurrentPage();
this.initCountPage();
}
/**
* 初始化当前页数
* @author HuangJingNa
* @date 2019年12月23日 下午3:25:35
*
*/
public void initCurrentPage() {
if(this.currentPage == null || this.currentPage <= 0) {
this.currentPage = 1;
}
}
/**
* 初始化每页显示的条数
* @author HuangJingNa
* @date 2019年12月23日 下午3:26:54
*
*/
public void initCountPage() {
//没有,以及小于下限
if(this.countPage == null || this.countPage <= 10) {
this.countPage = 10;
}
//大于上限
if(this.countPage >= 100) {
this.countPage = 100;
}
}
/**
* 计算起始索引
* @author HuangJingNa
* @date 2019年12月23日 下午3:23:07
*
*/
public static Integer countIndexStart(int currentPage, int countPage) {
return (currentPage - 1) * countPage;
}
public int countIndexStart() {
//(当前页数-1)*每页显示的条数
return (currentPage - 1) * countPage;
}
}
2.2 controller层
/**
* 根据用户昵称/用户账号/用户类别分页查看所有的用户
* @author HuangJingNa
* @date 2019年12月23日 下午3:30:16
*
* @return
*/
@GetMapping("find_user_all")
public Object findUserAll(
UserFindUserAllParam userFindUserAllParam) throws Exception{
return userService.findUserAll(userFindUserAllParam);
}
controller 中传递的参数
package cn.kooun.pojo.params;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 分页查询所有用户参数封装
* @author HuangJingNa
* @date 2019年12月23日 下午3:32:07
*
*/
@Getter
@Setter
@ToString
public class UserFindUserAllParam {
/**起始页数*/
private Integer pageStart;
/**用户昵称*/
private String userNickName;
/**用户账号*/
private String username;
/**用户类别*/
private Integer userType;
}
2.3 service层
/**
* 根据用户昵称/用户账号/用户类别分页查看所有的用户
* @author HuangJingNa
* @date 2019年12月23日 下午3:33:01
*
* @param userFindUserAll
* @return
*/
public Object findUserAll(UserFindUserAllParam userFindUserAllParam) throws Exception{
//校验数据
Object result = this.checkFindUserAll(userFindUserAllParam);
if(result != null) {
return result;
}
//封装分页数据
PageEntity pageEntity = packagePageParam(userFindUserAllParam);
//返回分页数据
return ResultUtils.success(pageEntity);
}
/**
* 封装分页数据
* @author HuangJingNa
* @date 2019年12月23日 下午4:14:50
*
* @param userFindUserAllParam
* @return
*/
private PageEntity packagePageParam(UserFindUserAllParam userFindUserAllParam) {
PageEntity pageEntity = new PageEntity(userFindUserAllParam.getPageStart());
//获取用户总记录数
int count = userMapper.findUserCountByPageParam(userFindUserAllParam);
//根据用户昵称/用户账号/用户类别分页查看所有的用户
List<Map<String, Object>> data = userMapper.findUserDataPageByPageParam(
pageEntity.getCountPage(),
pageEntity.countIndexStart(),
userFindUserAllParam);
pageEntity.setDataPage(data);
pageEntity.setTotal(count);
return pageEntity;
}
/**
* 根据用户昵称/用户账号/用户类别分页查看所有的用户_数据校验
* @author HuangJingNa
* @date 2019年12月23日 下午3:49:39
*
* @param userFindUserAllParam
* @return
*/
private Object checkFindUserAll(UserFindUserAllParam userFindUserAllParam) {
String userNickName = userFindUserAllParam.getUserNickName();
String username = userFindUserAllParam.getUsername();
Integer userType = userFindUserAllParam.getUserType();
//过滤昵称
if(!StringUtils.isEmpty(userNickName)) {
userFindUserAllParam.setUserNickName(SearchUtils.filterKeyWord(userNickName));
}
//过滤账号
if(!StringUtils.isEmpty(username)) {
userFindUserAllParam.setUsername(SearchUtils.filterKeyWord(username));
}
//过滤类型
if(userType != null) {
if(userType < 0 || userType > 1) {
userFindUserAllParam.setUserType(1);
}
}
return null;
}
2.4 dao层中的.java
/**
* 获取用户总记录数
* @author HuangJingNa
* @date 2019年12月23日 下午3:55:27
*
* @param userFindUserAllParam
* @return
*/
int findUserCountByPageParam(@Param("pageParam")UserFindUserAllParam pageParam);
/**
* 根据用户昵称/用户账号/用户类别分页查看所有的用户
* @author HuangJingNa
* @date 2019年12月23日 下午3:56:08
*
* @param countPage
* @param countIndexStart
* @param userFindUserAllParam
* @return
*/
List<Map<String, Object>> findUserDataPageByPageParam(
@Param("countPage")int countPage,
@Param("indexStart")int indexStart,
@Param("pageParam")UserFindUserAllParam pageParam);
dao层中的mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kooun.mapper.UserMapper">
<sql id="userPageselect">
SELECT
u.id userId,
u.create_time userCreateTime,
u.update_time userUpdateTime,
u.username UserName,
u.nick_name userNickName,
(
CASE u.type
WHEN 0 THEN
'管理员'
WHEN 1 THEN
'用户'
ELSE
'未知用户'
END
) userType
FROM
u_user u
</sql>
<sql id="userPageTotalSelect">
SELECT
COUNT(u.id)
FROM
u_user u
</sql>
<!-- 获取用户总记录数 -->
<select id="findUserCountByPageParam" resultType="int">
<include refid="userPageTotalSelect" />
<where>
<if test="pageParam.username != null">
u.username LIKE #{pageParam.username}
</if>
<if test="pageParam.userNickName != null">
OR u.nick_name LIKE #{pageParam.userNickName}
</if>
<if test="pageParam.userType != null">
OR u.type = #{pageParam.userType}
</if>
</where>
</select>
<!-- 根据用户昵称/用户账号/用户类别分页查看所有的用户 -->
<select id="findUserDataPageByPageParam" resultType="map">
<include refid="userPageselect" />
<where>
<if test="pageParam.username != null">
u.username LIKE #{pageParam.username}
</if>
<if test="pageParam.userNickName != null">
OR u.nick_name LIKE #{pageParam.userNickName}
</if>
<if test="pageParam.userType != null">
OR u.type = #{pageParam.userType}
</if>
</where>
LIMIT #{indexStart},#{countPage}
</select>
</mapper>
2.5 SearchUtils模糊查询工具
package cn.kooun.common.search;
import org.springframework.util.StringUtils;
/**
* 搜索工具类
*
* @author chenWei
* @date 2019年9月18日 下午3:54:52
*
*/
public class SearchUtils {
/**
* 过滤关键词
* @author chenWei
* @date 2019年9月18日 下午4:13:32
* @param keyWord
* @return
*/
public static String filterKeyWord(String keyWord) {
/*
* 将关键词过滤掉标点符号,然后每个字符的间隔都拼接上%号
* 执行sql like模糊查询能匹配更多数据
*/
keyWord = keyWord.replaceAll("\p{Punct}", "").trim();
if (keyWord.length() < 20) {
keyWord = keyWord.substring(0, keyWord.length());
} else {
keyWord = keyWord.substring(0, 20);
}
if(StringUtils.isEmpty(keyWord)) {
return keyWord;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keyWord.length(); i++) {
sb.append("%").append(keyWord.charAt(i));
}
sb.append("%");
return sb.toString();
}
}
-
由于数据库查询,一次性查出来的数据有可能过多,这样会造成数据库内存溢出(丢失数据),所以需要用到分页查询
-
分页参数封装,一般需要封装的参数:当前页数、总记录数、每页显示条数、分页数据;
-
同时,我们需要计算开始下标索引值:(当前页数-1)* 每页显示的条数,用于查询语句limit中的开始下标索引值;
-
以及每页显示条数的赋值(一般是系统自动赋值的,除了管理系统,客户端可能会主动赋值;所以需要设置其上限和下限),用户查询语句limit中的显示条数;
-
需要设置当前页数(若客户端没有传递当前页数,默认进入的是第一页)
-
由于查询条件是模糊查询的,需要每个字每个字重装去进行搜索(需要利用到搜索框架)