利用MyBatis实现分页
- 分页介绍
- 分页的sql语句实现
- 在Java中描述并处理分页
- 获取每页数据
- MyBatis映射文件中的操作
- 在Servlet中的响应处理
- 发送分页请求
- Servlet响应请求
- 结尾
分页介绍
我们可以在各个应用app或者网页上看到分页,分页也是数据展现的一种重要形式。
分页在开发中通常用原生的SQL来实现分页功能。分页所需要的数据通常有(当前页码,总记录数,总页数,每页大小,当前页数据(List))。总页数是根据总记录数与每页大小运算得来的。会把这些数据获取后再封装成分页的工具类对象。
分页的sql语句实现
我们在分页的页面可以看到每一页的数据都是一次查询,每一页的数据量都是固定的,用sql语句将数据分页本质就是分多次将其数据查询出来
select * from table limit 0,3 --mysql的实现
上面就将数据表的从第一条数据开始,往后查询三条数据的结果集显示出来了,我们再来看一下分页的sql语句变化过程:
select * from table limit 0,3 --第一页
select * from table limit 3,3 --第二页
select * from table limit 6,3 --第三页
select * from table limit 9,3 --第四页
从上面就可以看到,查出来的数据的每一页都是3笔,现在我们来列出起始偏移的规律
0,3 --> 0*3 = 0
3,3 --> 1*3 = 3
6,3 --> 2*3 = 6
9,3 --> 3*3 = 9
我们可以通过分析发现其中的运算系数规律,比如变化的0,1,2,3将之与每页的页数相乘就可以得出每一页的起始数据位置,而不与其上一页数据重叠。
这时基本可以开始编写代码了,但是我们经过思考会发现人们通常的数数习惯会从1开始数,所以我们最终列出的起始偏移量公式为:(当前页码-1)x每页显示的数据量:
0,3 --> (1-1)*3 = 0
3,3 --> (2-1)*3 = 3
6,3 --> (3-1)*3 = 6
9,3 --> (4-1)*3 = 9
那么最后写进代码的sql语句为:
select * from table limit (当前页码-1)*每页显示的数据量,页面数据量
在Java中描述并处理分页
我们可以把所有的分页数据全部封装,为了通用,工具做成泛型类。
import java.util.List;
public class PageUtil<T> {
/**
* 当前页
*/
private int pageIndex;
/**
* 每页大小
*/
private int pageSize;
/**
* 总记录数
*/
private int totalCount;
/**
* 总页数,可以通过每页大小和总记录数运算得来
*/
private int totalPageNum;
/**
* 当前页的数据
*/
private List<T> list;
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPageNum() {
return totalPageNum;
}
public void setTotalPageNum(int totalPageNum) {
this.totalPageNum = totalPageNum;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
这个类对当前页码、每页大小、总记录数、总页数、每页的所有数据进行了简单封装,今后我们对分页进行实现就会省很多重复代码
下面就来解决这个类中的获取每页所有数据进行一个讲解
获取每页数据
/**
* 这个方法将当前页码与页面大小作为参数进行传递,因为这两个参数是关键数据
*/
public PageUtil<User> getUserList(int currentPageNo, int pageSize) {
//分页工具类
PageUtil<User> p = new PageUtil<>();
int rowCount = 0; //总记录数
List<User> userList = null;
//这句代码会在下篇文章中讲到,他的目的就是获取与数据库的会话(连接)
SqlSession session = MybatisUtil.getSqlSession();
try {
//利用MyBatis对接口进行实现
UserDao dao = session.getMapper(UserDao.class);
//获取总数据量,后面会讲到
rowCount = dao.getUserCount();
//参数比较多,可以封装成Map传递,也可以用工具类对象传递
Map<String,Object> map = new HashMap<String,Object>();
map.put("currentPageNo", (currentPageNo-1)*pageSize);
map.put("pageSize", pageSize);
//获取分页的数据,后面会讲到
userList = dao.getUserList(map);
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭会话
session.close();
}
//从第一个参数获取的当前页码currentPageNo
p.setPageIndex(currentPageNo);
//从数据库中获取的总数据量rowCount
p.setTotalCount(rowCount);
//从第二个参数获取的每个页面大小pageSize
p.setPageSize(pageSize);
//运算出总页数
if(rowCount%pageSize ==0)
//如果总数据量刚好被当前页面大小整除,那就可以直接相除算出页数
p.setTotalPageNum(rowCount/pageSize);
else {
//如果总数据量不能被当前页面大小整除,那就相除后再加上1,这样能保证
//多余的数据页面会显示出来
p.setTotalPageNum(rowCount/pageSize+1);
}
//当前页的数据
p.setList(userList);
//返回分页所有的数据。
return p;
}
这个方法对数据进行了处理,以后获取分页数据时就不用再处理一些繁琐的数据了,直接调用这个方法获取数据就可以了
MyBatis映射文件中的操作
<select id="getUserCount" resultType="int">
select count(1) from User
</select>
<select id="getUserList" parameterType="map" resultType="User">
select * from user
limit #{currentPageNo},#{pageSize}
</select>
可以看到select标签中parameterType值为map,这就对应着这个方法的形参的类型Map,所以其中的currentPageNo与pageSize都是Map中的键所对应的值。
在Servlet中的响应处理
现在我们可以在Servlet中响应前端的分页操作
当我们点击下一页或点击页码时发送请求给到Servlet,现在我们来看响应是如何给到前端页面以及前端页面是如何请求Servlet的
发送分页请求
前端页面我们通过ajax请求后端Servlet
function pageFun(PageNum) {
$.ajax({
type: "get",
url: "/Project/UserServlet",
data: {name: "userPage", index: PageNum},
dataType: "json",
success: function (data) {
$(data).each(function () {
$("#tab").append("<tr><td>"+this.UserName+"</td></tr>");
})
},
error: function () {
alert("FBI WARING");
}
})
}
当我们点击下一页或者直接点击页码就会触发该pageFun的方法,并动态的响应到网页中。
Servlet响应请求
UserService service = new UserServiceImpl();
int pageIndex = 1; //默认是第1页
if(request.getParameter("index")!=null) {
pageIndex = Integer.parseInt(request.getParameter("index"));
}
PageUtil<User> page = service.getUserList(pageIndex, 3);
String pageJson = JSON.toJSONString(page.list);
response.getWrite().print(pageJson);
这里利用了Json将集合发送到前端遍历显示分页内容,在这里我只着重介绍分页的后端功能实现,对于前端的设计以及前后端交互我只做出粗略的演示。