mybatis分页、延迟加载、立即加载、一级缓存、二级缓存
- 分页
- 延迟加载和立即加载
- 缓存
- 一级缓存
- 二级缓存
分页
分类:
- 使用Limit,来进行分页;物理分页
- 使用RowBounds集合来保存分页需要数据,来进行分页;逻辑分页;本质是全查,只是显示部分
- 使用分页插件来进行分页;物理分页
方式一:
//limit分页
@Select("select * from student limit #{arg0},#{arg1}")
public List<Student> selectStudentLimit(int sp,int cp);
//获取数据
List<Student> slist = sm.selectStudentLimit((1-1)*3,3);
方式二:
//RowBounders
public List<Student> selectStudentRB(RowBounds rb);
//获取数据
List<Student> slist = sm.selectStudentRB(new RowBounds(2,3));
方式三:
首先导入两个jar包:
配置插件:
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
//分页
@Select("select * from student")
public List<Student> selectStudentPageHelper();
调用:
Page<Object> page = PageHelper.startPage(1, 3);
List<Student> list = mapper.selectStudentPageHelper();
list.forEach(System.out::println);
//page对象可以获取
System.out.println(page);
//详细分页对象
PageInfo<Studnet> pageinfo = new PageInfo<Student>(list,3);
System.out.println(pageinfo);
字段 | 含义 |
---|---|
pageNum | 当前页的页码 |
pageSize | 每页显示的条数 |
size | 当前页显示的真实条数 |
total | 总记录数 |
pages | 总页数 |
prePage | 上一页的页码 |
nextPage | 下一页的页码 |
isFirstPage / isLastPage | 是否为第一页/是否为最后一页 |
hasPrevivousPage / hasNextPage | 是否存在上一页/是否存在下一页 |
navigatePages | d导航分页的码数 |
navigatepageNums | d导航分页的页码,[1,2,3,4…] |
延迟加载和立即加载
立即加载:不管用不用信息,只要调用,马上发起查询并进行加载;通常,当 一对一或者多对一的时候需要立即加载
比如:当我们查询学生信息时,就需要知道学生在哪个班级中,所以就需要立马去查询班级的信息
延迟加载:在真正使用数据时才发起查询,不用的时候不查询,按需加载(也叫 懒加载);通常, 一对多,或者多对多的是需要使用延迟加载
比如:在查询班级信息,每个班级都会有很多的学生(假如每个班有100个学生),如果我们只是查看班级信息,但是学生对象也会加载到内存中,会造成浪费。所以我门需要进行懒加载,当确实需要查看班级中的学生信息,我门在进行加载班级中的学生信息。
延迟加载的配置:
如果设置 lazyLoadingEnabled = false,则禁用延迟加载,会级联加载所有关联对象的数据
如果设置 lazyLoadingEnabled = true,默认情况下mybatis 是按层级延时加载的。
aggressiveLazyLoading = true,mybatis 是按层级延时加载
aggressiveLazyLoading = false,mybatis 按需求加载。
sqlmapper中:
注解方式开启:
//开启二级缓存
@CacheNamespace(blocking = true)
public interface StudentMapper {
...
}
缓存
什么是缓存:缓存(cache),数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在缓冲区中,应用程序从缓冲区读取数据。
特点:数据库取出的数据保存在内存中,具备快速读取和使用。
限制:读取时无需再从数据库获取,数据可能不是最新的;
命中、未命中:需要的数据在缓存中找到结果为命中;需要的数据在缓存中未找到,重新获取为未命中。
功能:减少 Java Application 与数据库的交互次数,从而提升序的运行效率;
适合使用缓存:经常查询并且不经常改变的 、数据的正确与否对最终结果影响不大的 。比如:一个公司的介绍,新闻等
不适合使用缓存:经常改变的数据、数据的正确与否对最终结果影响很大。比如商品的库存,股市的牌价等
数据的正确与否对最终结果影响很大
比如商品的库存,股市的牌价等
一级缓存
一级缓存会话 session 级别的缓存,针对一次会话操作内,默认开启
public static void main(String[] args) {
SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper stuMapper = sqlSession.getMapper(StudentMapper.class);
Student s = stuMapper.findStudentBySid(1);
//SqlSession sqlSession2 = DaoUtil.getSqlSession();
//StudentMapper stuMapper2 = sqlSession2.getMapper(StudentMapper.class);
Student s2 = stuMapper2.findStudentBySid(1);
System.out.println(s == s2);//true
// DaoUtil.closeResource(sqlSession);
// 1. 不同的SqlSession
SqlSession sqlSession2 = DaoUtil.getSqlSession();
StudentMapper stuMapper2 = sqlSession2.getMapper(StudentMapper.class);
Student s2 = stuMapper2.findStudentBySid(1);
System.out.println(s2);
System.out.println(s == s2);//false
DaoUtil.closeResource(sqlSession2);
// 2. 在同一个sqlSession中进行增删改操作
int ret = stuMapper.addStudent(new Student());
System.out.println(ret);
// 3. 主动的清空缓存
sqlSession.clearCache();
// 4. sql语句不同
Student s2 = stuMapper.findStudentBySid(1);
System.out.println(s2);
System.out.println(s == s2);
DaoUtil.closeResource(sqlSession);
}
一级缓存失效的四种情况:
- 不同SqlSession对应不同的一级缓存
- 同一个SqlSession单查询条件不同
- 同一个SqlSession两次查询期间执行了任何一次增删改操作
- 同一个SqlSession两次查询期间手动清空了缓存
二级缓存
不会用的
特点:
- Mybatis的二级缓存相对于一级缓存来说,实现了缓存数据的共享,可控性也更强;
- 极大可能会出现错误数据,有设计上的缺陷, 安全使用的条件比较苛刻;
- 分布式环境下,必然会出现读取到错误 数据,所以不推荐使用。