一、延迟加载和立即加载
延迟加载:在真正使用数据的时候才会发起查询,不用的时候不加载,按需加载。
立即加载:不管用不用,只要已调用方法就立即查询。
我们一般在一对一的时候用立即加载,一对多的时候用延迟加载。
1.延迟加载
以上是一对一延迟加载,主要是使用association标签,property就是指向的类,column是两个表关联的id,javaType返回的数据类型,select填需要调用的查询方法的地址(查询用户的唯一标识,能够根据uid查询的相关标识)。
以上是一对多的延迟加载,主要是使用collection标签,property就是指向的类,column是两个表关联的id,ofType返回的数据类型,select填需要调用的查询方法的地址。
二、一级缓存和二级缓存
缓存就是存在于内存中的数据,主要是为了减少和数据库的交互,提高效率。但是像股市价格,银行汇率等功能的实现就不太适合。
1.一级缓存
一级缓存一般都是自动的,存在于sqlSession对象中。当我们执行查询的时候,结果存入到sqlSession提供的一块区域当中。这个区域就是一个Map,在此查询相同的内容时,就会先去sqlSession中去查找。有的话就直接使用,当sqlSession消失时,一级缓存也就消失了。
一般都是自动就使用了,当途中有增删改的时候,会自动释放内存。
代码如下(示例):
@Test
public void testFristLevelCache(){
User user1 = userDao.findById(42);
System.out.println(user1);
sqlSession.clearCache(); //此处为清空一级缓存,不然user2将会直接使用user1的值。
User user2 = userDao.findById(42);
System.out.println(user2);
System.out.println(user1 == user2);
}
此处user1查询后,user2接着查询。最后输出的结果会是true。但是上面输出的是false,是因为在user2查询之前sqlSession.clearCache();已经清楚了sqlSession
2.二级缓存
二级缓存是SqlSessionFactory对象的缓存,有同一个SqlSessionFactory对象创建的sqlSession共享其缓存。
使用步骤:
- 让Mybatis支持二级缓存(在sqlMapconfig.xml中设置)
- 让当前映射文件支持二级缓存(在IUserDao.xml中设置)
4. 让当前操作支持(在select中设置)
设置完成后看实例代码:
@Test
public void testFristLevelCache(){
SqlSession sqlSession1 = factory.openSession(true);
IUserDao userDao1 = sqlSession1.getMapper(IUserDao.class);
User user1 = userDao1.findById(42);
System.out.println(user1);
sqlSession1.close(); //一级缓存消失
SqlSession sqlSession2 = factory.openSession(true);
IUserDao userDao2 = sqlSession2.getMapper(IUserDao.class);
User user2 = userDao2.findById(42);
System.out.println(user2);//此处的users用的是二级缓存,并没有进行查询
sqlSession2.close(); //一级缓存消失
System.out.println(user1 == user2); //此处的结果是false,是因为sqlSessionFactory中的二级缓存是共享的,需要用的时候取出数据还会在赋一次值。
}
此处的sqlSession1 和sqlSession2 均是由同一个factory创建,因此可以共享二级缓存。当user1有结果后,user2可以直接共享不用进行查询。注意的是,使用前需要关闭一级缓存,否则会影响二级缓存。(我的理解是:两者不能共存)