前言:学习hibernate & mybatis等持久层框架的时候,不外乎对数据库的增删改查操作。而使用最多的当是数据库的查找操作, 而当数据库数据过多时,符合查找条件的数据可能也会是很庞大的数据。往往在这个时候,我们都不会希望一次性的将所有的数据一起性读取出来,并且显示在UI界面上。常用的操作,就是对查找到的数据进行分页,每次处理小部分数据。这样每次处理的数据量就会在可控的范围,UI的展示也会很协调。
问题:面对上面的问题,今天我们就来进行基于mybatis和MySql进行分页功能的实现。常见的数据分页有哪几种实现??基于数组的分页实现?基于sql语句的分页实现?还是通过拦截器进行数据分页功能?还是通过RowBounds参数进行物理分页?几种都是常用的分页实现原理,接下来就按照数组、sql语句,拦截器和RowBounds的方式介绍分页功能。
一.借助数组进行分页
原理:进行数据库查询操作时,获取到数据库中所有满足条件的记录,保存在应用的临时数组中,再通过List的subList方法,获取到满足条件的所有记录。
实现:
首先在dao层,创建StudentMapper接口,用于对数据库的操作。在接口中定义通过数组分页的查询方法,如下所示:
List<Student> queryStudentsByArray();
方法很简单,就是获取所有的数据,通过list接收后进行分页操作。
创建StudentMapper.xml文件,编写查询的sql语句:
<select id="queryStudentsByArray" resultMap="studentmapper">
select * from student
</select>
可以看出再编写sql语句的时候,我们并没有作任何分页的相关操作。这里是查询到所有的学生信息。
接下来在service层获取数据并且进行分页实现:
定义IStuService接口,并且定义分页方法:
List<Student> queryStudentsByArray(int currPage, int pageSize);
通过接收currPage参数表示显示第几页的数据,pageSize表示每页显示的数据条数。
创建IStuService接口实现类StuServiceIml对方法进行实现,对获取到的数组通过currPage和pageSize进行分页:
@Override
public List<Student> queryStudentsByArray(int currPage, int pageSize) {
List<Student> students = studentMapper.queryStudentsByArray();
// 从第几条数据开始
int firstIndex = (currPage - 1) * pageSize;
// 到第几条数据结束
int lastIndex = currPage * pageSize;
return students.subList(firstIndex, lastIndex);
}
通过subList方法,获取到两个索引间的所有数据。
最后在controller中创建测试方法:
@ResponseBody
@RequestMapping("/student/array/{currPage}/{pageSize}")
public List<Student> getStudentByArray(@PathVariable("currPage") int currPage, @PathVariable("pageSize") int pageSize) {
List<Student> student = StuServiceIml.queryStudentsByArray(currPage, pageSize);
return student;
}
通过用户传入的currPage和pageSize获取指定数据。
测试:
首先我们来获取再没实现分页效果前获取到的所有数据,如下所示:
接下来在浏览器输入http://localhost:8080/student/student/array/1/2
测试实现了分页后的数据。获取第一页的数据,每页显示两条数据。
结果如下:
输出的是指定的从第0-2条数据,可见我们通过数组分页的功能是成功的。(这里因为用到了关联查询,所以看起来数据可能比较多)
缺点:数据库查询并返回所有的数据,而我们需要的只是极少数符合要求的数据。当数据量少时,还可以接受。当数据库数据量过大时,每次查询对数据库和程序的性能都会产生极大的影响。
二.借助Sql语句进行分页
在了解到通过数组分页的缺陷后,我们发现不能每次都对数据库中的所有数据都检索。然后在程序中对获取到的大量数据进行二次操作,这样对空间和性能都是极大的损耗。所以我们希望能直接在数据库语言中只检索符合条件的记录,不需要在通过程序对其作处理。这时,Sql语句分页技术横空出世。
实现:通过sql语句实现分页也是非常简单的,只是需要改变我们查询的语句就能实现了,即在sql语句后面添加limit分页语句。
首先还是在StudentMapper接口中添加sql语句查询的方法,如下:
List<Student> queryStudentsBySql(Map<String,Object> data);
然后在StudentMapper.xml文件中编写sql语句通过limiy关键字进行分页:
<select id="queryStudentsBySql" parameterType="map" resultMap="studentmapper">
select * from student limit #{currIndex} , #{pageSize}
</select>
接下来还是在IStuService接口中定义方法,并且在StuServiceIml中对sql分页实现。
List<Student> queryStudentsBySql(int currPage, int pageSize);
@Override
public List<Student> queryStudentsBySql(int currPage, int pageSize) {
Map<String, Object> data = new HashedMap();
data.put("currIndex", (currPag