MyBatis

1.MyBatis物理分页、逻辑分页

  • 物理分页:物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如 MySQL 数据库提供了 limit 关键字,程序员只需要编写带有 limit 关键字的 SQL语句语句,数据库返回的就是分页结果。
  • 逻辑分页 (内存分页):逻辑分页依赖的是程序员编写的代码。数据库返回的不是分页结果,而是全部数据,然后再由程序员通过代码获取分页数据,常用的操作是一次性从数据库中查询出全部数据并存储到 List 集合中,因为 List 集合有序,再根据索引获取指定范围的数据。

2.缓存

2.1.一级缓存

  • 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;
  • 不同的 SqlSession 之间的缓存是相互隔离的;用一个 SqlSession,可以通过配置使得在查询前清空缓存;任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

2.2.二级缓存

  • 存在于 SqlSessionFactory 生命周期中

  • 第一阶段:

    在第一个 SqlSession 中, 查询出 student 对象, 此时发送了 SQL 语句;student更改了name 属性,SqlSession 再次查询出 student1 对象, 此时不发送 SQL 语句, 日志中打印了 「Cache Hit Ratio」, 代表二级缓存使用了, 但是没有命中。 因为一级缓存先作用了。由于是一级缓存, 因此, 此时两个对象是相同的。调用了 sqlSession.close(),此时将数据序列化并保持到二级缓存中。

    第二阶段:

    新创建一个 sqlSession.close() 对象;查询出 student2 对象,直接从二级缓存中拿了数据, 因此没有发送 SQL 语句, 此时查了 3 个对象,但只有一个命中, 因此 命中率 1/3=0.333333;查询出 student3 对象,直接从二级缓存中拿了数据, 因此没有发送 SQL 语句, 此时查了 4 个对象,但只有一个命中, 因此命中率 2/4=0.5;由于 readOnly="true", 因此 student2 和 student3 都是反序列化得到的, 为不同的实例。