mybatis内置的分页是逻辑分页。比如说数据库中有100条数据,我们每页显示10条,mybatis是先把这100条数据取出放在内存中,然后从内存中取10条显示。如果数据量小的话这种方式还可以,但是当数据量很大(几万条数据)的时候,这种方式的性能就很低。看一个例子演示逻辑分页:
一、逻辑分页
1.添加接口方法:
public List<Student> findStudents(RowBounds rowBounds);
这个方法使用mybatis的逻辑分页显示数据。
2.方法实现:
<select id="findStudents" resultMap="StudentResult">
select * from t_student;
</select>
这里是查询所有的学生。
3.添加测试方法:
@Test
public void testFindStudent(){
logger.info("查询学生");
int offSet = 0, limit = 3;
RowBounds rowBounds = new RowBounds(offSet,limit);
List<Student> studentList = studentMapper.findStudents(rowBounds);
for(Student s:studentList){
System.out.println(s);
}
}
这里offSet代表从数据库中第几条数据开始读取,limit代表要读取的数据数目。这里演示分页,每页显示3条数据。
运行这个测试方法,控制台输出前3条数据。这个过程就演示了逻辑分页的过程,第2步中是把所有的数据都进行了查询,把所有的数据都放在了内存中。而第3步中只显示3条数据,就在内存中读取3条数据。
二、物理分页:逻辑分页是把所有的数据取出放在内存中,把需要显示的数据直接从内存中读取,这种方式当数据量很大的时候性能低下。物理分页是按照需要查询数据,需要多少数据,就直接在数据库中读取需要的数据。
1.添加接口方法:
public List<Student> findStudents2(Map<String,Object> map);
2.实现该方法:
<select id="findStudents2" parameterType="map" resultMap="StudentResult">
select * from t_student
<if test="start!=null and size!= null">
limit #{start},#{size}
</if>
</select>
这里使用map的方式把需要读取的数据传入,start代表读取的数据的索引,size代表读取的数据的数目。这里就实现了对需要的数据直接从数据库中读取。
3.添加测试方法:
@Test
public void testFindStudent2(){
logger.info("查询学生");
Map<String,Object> map = new HashMap<String,Object>();
map.put("start", 0);
map.put("size", 3);
List<Student> studentList = studentMapper.findStudents2(map);
for(Student s:studentList){
System.out.println(s);
}
}
这里读取前3条数据。运行测试方法,得到相应的数据信息。
以后在开发项目的时候,还是使用这种逻辑分页的效果要好。
三、mybatis缓存:这个与讲hibernate的时候讲到的缓存类似
Mybatis 默认情况下,MyBatis 启用一级缓存,即同一个SqlSession 接口对象调用了相同的select 语句,则直接会从缓存中返回结果,而不是再查询一次数据库(同一个用户查询多次相同的数据的时候只需要进行一次数据库查询操作,把查询结果放在缓存中,当再次查询的时候直接在缓存中读取);
开发者可以自己配置二级缓存,二级缓存是全局的(二级缓存可以理解成是不同的用户查询同样的数据,只需要一个用户查询一次即可,把查询的结果放在二级缓存中,当其他的用户需要的时候直接在二级缓存中读取);
默认情况下,select 使用缓存的,insert update delete 是不使用缓存的;
1.二级缓存配置方法如图:
只有一条<cache>配置语句。这里这条语句一定要放在namespace里面。这里size表示缓存cache中能容纳的最大元素数,默认是1024,这个数值随便调,只要服务器的内存够大。size的大小要根据服务器内存的大小以及并发量大小来调。
flushInterval:定义缓存刷新周期,上面配置为60秒,这个可以不写。
eviction:定义缓存的移除机制。比如上面配置的缓存最大是1024,当超过1024的时候,就需要把部分数据移除缓存。
readOnly:默认是false,可读可写,select就是读缓存中的数据,而update就是写缓存中的数据。实际情况中也就是select用到缓存。
看如下示例:
这里select标签中使用缓存属性useCache默认是true,表示使用缓存;清空缓存属性flushCache默认是false,表示不清空缓存。
insert标签中清空缓存属性flushCache默认是true,表示清空缓存。
了解缓存这个知识点即可,一般的项目用不到。除非并发量特别大的项目,需要考虑优化的时候,可以考虑开启二级缓存。