========================= MyBatis缓存机制之一级缓存 ========================= MyBatis缓存分为一级缓存和二级缓存。 public class MyBatisUtil { ... public static void closeSession() { SqlSession session = local.get(); if (session != null) { session.close(); local.set(null); } } ... } public interface MemberDao { ... public Member searchById(int id); public int modifyAge(@Param("id") int id, @Param("age") int age); ... } ... update t_member set age = #{age} where id = #{id} ... public class MemberDaoTest { ... @Test public void testSearchById() { SqlSession session = MyBatisUtil.getSession(); MemberDao dao = session.getMapper(MemberDao.class); System.out.println("\n第一次查询..."); System.out.println(dao.searchById(1)); System.out.println("\n第二次查询..."); System.out.println(dao.searchById(1)); session.clearCache(); System.out.println("\n第三次查询..."); System.out.println(dao.searchById(1)); System.out.println("\n第四次查询..."); System.out.println(dao.searchById(1)); MyBatisUtil.closeSession(); session = MyBatisUtil.getSession(); dao = session.getMapper(MemberDao.class); System.out.println("\n第五次查询..."); System.out.println(dao.searchById(1)); Member member = dao.searchById(1); member.setAge(member.getAge() + 1); System.out.println("\n第六次查询..."); System.out.println(dao.searchById(1)); session.clearCache(); System.out.println("\n第七次查询..."); System.out.println(dao.searchById(1)); member = dao.searchById(1); dao.modifyAge(member.getId(), member.getAge() + 1); System.out.println("\n第八次查询..."); System.out.println(dao.searchById(1)); SqlSession s = MyBatisUtil.getFactory().openSession(); MemberDao d = s.getMapper(MemberDao.class); Member m = d.searchById(1); d.modifyAge(m.getId(), m.getAge() + 1); s.commit(); System.out.println("\n第九次查询..."); System.out.println(dao.searchById(1)); } ... } 运行测试用例: 第一次查询... [main] DEBUG - ==> Preparing: select id, nick, gender, age, city from t_member where id = ? sg :==> Preparing: select id, nick, gender, age, city from t_member where id = ? [main] DEBUG - ==> Parameters: 1(Integer)sg :==> Parameters: 1(Integer) [main] DEBUG - <== Total: 1sg :<== Total: 1 Member(id=1, nick=john, gender=男, age=20, city=北京) 第二次查询... Member(id=1, nick=john, gender=男, age=20, city=北京) 第三次查询... [main] DEBUG - ==> Preparing: select id, nick, gender, age, city from t_member where id = ? sg :==> Preparing: select id, nick, gender, age, city from t_member where id = ? [main] DEBUG - ==> Parameters: 1(Integer)sg :==> Parameters: 1(Integer) [main] DEBUG - <== Total: 1sg :<== Total: 1 Member(id=1, nick=john, gender=男, age=20, city=北京) 第四次查询... Member(id=1, nick=john, gender=男, age=20, city=北京) 第五次查询... [main] DEBUG - ==> Preparing: select id, nick, gender, age, city from t_member where id = ? sg :==> Preparing: select id, nick, gender, age, city from t_member where id = ? [main] DEBUG - ==> Parameters: 1(Integer)sg :==> Parameters: 1(Integer) [main] DEBUG - <== Total: 1sg :<== Total: 1 Member(id=1, nick=john, gender=男, age=20, city=北京) 第六次查询... Member(id=1, nick=john, gender=男, age=21, city=北京) <库中20> 第七次查询... [main] DEBUG - ==> Preparing: select id, nick, gender, age, city from t_member where id = ? sg :==> Preparing: select id, nick, gender, age, city from t_member where id = ? [main] DEBUG - ==> Parameters: 1(Integer)sg :==> Parameters: 1(Integer) [main] DEBUG - <== Total: 1sg :<== Total: 1 Member(id=1, nick=john, gender=男, age=20, city=北京) 第八次查询... [main] DEBUG - ==> Preparing: select id, nick, gender, age, city from t_member where id = ? sg :==> Preparing: select id, nick, gender, age, city from t_member where id = ? [main] DEBUG - ==> Parameters: 1(Integer)sg :==> Parameters: 1(Integer) [main] DEBUG - <== Total: 1sg :<== Total: 1 Member(id=1, nick=john, gender=男, age=21, city=北京) <库中21> 第九次查询... Member(id=1, nick=john, gender=男, age=21, city=北京) <库中22> 例程:Dynamic 一级缓存具有如下特性: - 一级缓存也叫会话(SqlSession)级缓存,无需手动开启即可直接使用 - 每个SqlSession对象都有独立的缓存区,相互之间不共享 - 若欲通过缓存提高多次查询的性能,必须使用同一个SqlSession对象 - 缓存中存放的是查询所获得的实体对象,修改该对象实际是在修改缓存 - 及时清空缓存(clearCache)有利于保持与数据库的一致,但会牺牲性能 - 在会话内更新数据库,会导致缓存失效,保证缓存与数据库一致 - 在会话外修改数据库,不会使缓存失效,有可能导致数据不一致