首先要明确分页查询SQL语句怎么写:
SELECT * FROM `user` LIMIT startIndex,count
startIndex:指定从第哪一条条记录开始查询(不包含当前记录,即实际是从startIndex+1开始的)
count: 指定查询多少条数据
此外,还需要得到总记录数,总页数。这些可能都是需要在前端显示的。
新建page包并在包下新创建Page类,代码如下:
package com.yky.springboot.page;
import java.util.List;
public class Page<T> {
//每页显示的记录数
private int lineSize = 5;
//总记录数
private long totalRecord;
//用户指定的页数
private int currentPage;
//起始位置
private long startIndex;
//总页数
int pageCount;
List<T> list;
public Page(int currentPage, long totalRecord, int lineSize) {
this.currentPage = currentPage;
this.totalRecord = totalRecord;
this.lineSize = lineSize;
//计算出pageCount
this.pageCount = (int) ((totalRecord % lineSize) != 0 ? ((totalRecord / lineSize) + 1) : (totalRecord / lineSize));
//计算出起始位置,注意,从0下标开始
this.startIndex = (currentPage - 1) * lineSize;
}
public long getStartIndex() {
return (currentPage - 1) * lineSize;
}
public void setStartIndex(long startIndex) {
this.startIndex = startIndex;
}
public int getLineSize() {
return lineSize;
}
public void setLineSize(int lineSize) {
this.lineSize = lineSize;
}
public long getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(long totalRecord) {
this.totalRecord = totalRecord;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
@Override
public String toString() {
return "Page{" +
"lineSize=" + lineSize +
", totalRecord=" + totalRecord +
", currentPage=" + currentPage +
", pageCount=" + pageCount +
", list=" + list +
'}';
}
}
Page类的构造方法需要传入三个参数,分别是:
通过传入这三个参数可以算出:
Dao层需要针对两个查询接口进行编写,一是查询符合条件的总记录数,二是查询符合条件的具体记录。
Mapper接口代码:
/**
* 根据查询条件获取总记录数
* 在这里直接传一个user对象
* 使用user.name进行模糊查询
* 使用user.phone进行精确查询
* @param user
* @return
*/
Long getTotalRecord(@Param("u") User user);
/**
* 根据查询条件获取总记录数
* 在这里直接传一个user对象
* 使用user.name进行模糊查询
* 使用user.phone进行精确查询
* @param page
* @param user
* @return
*/
List<User> selectPage(@Param("p") Page page, @Param("u") User user);
xml映射文件代码
<select id="getTotalRecord" resultType="java.lang.Long">
SELECT COUNT(1) FROM `user`
<where>
<if test="u.name != null and u.name != ''">
name LIKE CONCAT('%',#{u.name},'%')
if>
<if test="u.phone != null and u.phone != ''">
AND phone = #{u.phone}
if>
where>
select>
<select id="selectPage" resultType="com.yky.springboot.entities.User">
SELECT * FROM `user`
<where>
<if test="u.name != null and u.name != ''">
name LIKE CONCAT('%',#{u.name},'%')
if>
<if test="u.phone != null and u.phone != ''">
AND phone = #{u.phone}
if>
where>
LIMIT #{p.startIndex},#{p.lineSize}
select>
测试
@Test
void pageMapperTest() {
User user = new User();
user.setName("小");
//查询第一页
Long totalRecord = userMapper.getTotalRecord(user);
Page page = new Page(1, totalRecord, 3);
List<User> userList = userMapper.selectPage(page, user);
System.out.println("totalRecord" + totalRecord);
System.out.println("userList:" + userList);
//查询第二页
Page page1 = new Page(2, totalRecord, 3);
userList = userMapper.selectPage(page1, user);
System.out.println("userList:" + userList);
//使用phone条件查询
User user1 = new User();
user1.setPhone("18888888888");
totalRecord = userMapper.getTotalRecord(user1);
Page page2 = new Page(1, totalRecord, 3);
userList = userMapper.selectPage(page, user1);
System.out.println("totalRecord" + totalRecord);
System.out.println("userList:" + userList);
}
dao层在上一步我们已经写好了,接下来就是在service整合dao层的两个查询了。
在这里service层要做的事情有:
在service包下新创建UserService.java文件代码如下(注意:这里只定义接口,具体实现不再这里):
public interface UserService {
/**
* 分页查询
* @param currentPage 当前页码
* @param lineSize 每页数据个数
* @param user user对象
* @return
*/
Page<User> getPageData(int currentPage, int lineSize, User user);
}
在service.impl包下新建文件UserServiceImpl.java代码如下(这里写接口的具体实现):
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public Page<User> getPageData(int currentPage, int lineSize, User user) {
//得到符合条件的总记录数
Long totalRecord = userMapper.getTotalRecord(user);
//构建page对象
Page<User> page = new Page<>(currentPage,totalRecord,lineSize);
//分页查询
List<User> userList = userMapper.selectPage(page, user);
//将查询结果封装到page里
page.setList(userList);
return page;
}
}
该类实现了UserService接口,至此Service层代码就写好了。
接下来就是编写Controller层,前端传递分页条件,后端返回对应的数据。在controller包下新创建UserController.java文件,并添加以下代码
@Controller
@RequestMapping(value = "/user")
public class UserController {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UserService userService;
@PostMapping(value = "/{currentPage}/{lineSize}")
@ResponseBody
public Page<User> list(@RequestBody User user, @PathVariable("currentPage") Integer currentPage, @PathVariable("lineSize") Integer lineSize) {
Page<User> page = userService.getPageData(currentPage, lineSize, user);
System.out.println(page);
return page;
}
}
在这里页码和单页数据大小通过PathValue传入,筛选条件通过JSON对象传入,接口返回JSON字符串。
利用Postman进行测试
查询第一页数据,筛选条件是name中含有“小”字。
查询第二页数据
后话:为了更规范,在这里可以自定义一个Result对象,将page对象封装到Result对象中,最后将Result对象返回给前端。
{
"code":200,
"message":"OK",
"data":{
"lineSize": 3,
"totalRecord": 5,
"currentPage": 2,
"startIndex": 3,
"pageCount": 2,
"list": [
{
"id": 4,
"name": "小张",
"phone": "15555555555",
"birthday": "2020-03-16T06:37:25.000+0000"
},
{
"id": 5,
"name": "小刘",
"phone": "12345678",
"birthday": "2020-03-16T06:48:08.000+0000"
}
]
}
}