继上篇博文!!!
1、在mybatis的主配置文件中SqlMapConfig.xml开启延迟加载
2、在OrdersMapper.xml加入
3、在OrdersMapper.java加入
//使用懒加载查询所有的订单并且关联用户
public List
4、为了测试是否实现了懒加载,添加log4j.properties文件,方便查看查询语句
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
5、测试懒加载
//测试使用懒加载查询所有的订单信息并关联用户
@Test
public void testFindOrdersUserByLazy(){
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper mapper = sqlSession.getMapper(OrdersMapper.class);
List
if(findOrdersUser != null && findOrdersUser.size() > 0 ){
for(Orders order: findOrdersUser){
System.out.println("第一条订单"+order+"");
//当执行下一行出现查询语句,说明懒加载成功
System.out.println(order.getUser());
}
}
}
6、小结
作用:
当需要查询关联信息时再去数据库查询,默认不去关联查询,提高数据库性能。
只有使用resultMap支持延迟加载设置。
场合:
当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。
当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resultType或resultMap完成映射。
1、原理
一级缓存区域是根据SqlSession为单位划分的。每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象,当sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
2、测试一级缓存:
a、测试是否为sqlSession为单位划分的
@Test
public void testFirstCache1(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.findUserById(1);
System.out.println(user1);
//此时执行下一行代码,并不会发出查询句
User user2 = mapper.findUserById(1);
System.out.println(user2);
sqlSession.close();
}
@Test
public void testFirstCache2(){
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper.findUserById(1);
System.out.println(user1);
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
//此时执行下一行代码,会发出查询语句
User user2 = mapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
b、测试是否sqlSession提交完,就会清空缓存区域
//测试是否sqlSession提交完,就会清空缓存区域
@Test
public void testFirstCache3(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1);
user.setUsername("bingo");
user.setAddress("广州");
user.setGender("男");
user.setBirthday(new Date());
mapper.updateUser(user);
sqlSession.commit();
//当执行下一行语名时会发出查询语句,说明当更新提交后,一级缓存区域会被清空
User user2 = mapper.findUserById(1);
sqlSession.close();
}
1、原理:
二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象,当sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
2、需要配置:
a、在SqlMapConfig.xml的全局配置中加入
b、在需要使用二级缓存的mapper映射文件中加入
c、需要查询的pojo对象实现序列化Serializable
此时在UserMapper.xml中加入
3、测试二级缓存
a、测试二级缓存是不是以mapper的namespace划分的
@Test
public void testSecondCache(){
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.findUserById(1);
System.out.println(user1);
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
//此时执行下一行代码,不会发出查询语句,则二级缓存是以mapper划分的
User user2 = mapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
b、测试sqlSession更新数据时是否清空二级缓存
@Test
public void testSecondCache2(){
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user = mapper1.findUserById(1);
user.setUsername("bingo");
user.setAddress("广州");
user.setGender("男");
user.setBirthday(new Date());
mapper1.updateUser(user);
sqlSession1.commit();
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
//当执行下一行语名时会发出查询语句,说明当更新提交后,二级缓存区域会被清空
User user2 = mapper2.findUserById(1);
sqlSession2.close();
}
4、二级缓存
例如:
FIFO机制表示当缓存满了,采用按对象进入缓存的顺序来移除它们,
默认的是 LRU,表示移除最长时间不被使用的对象。
flushInterval表示缓存每60秒刷新,默认是不设置即不刷新
size表示缓存的对象数目和运行环境的可用内存资源数目,默认值是1024。
readOnly表示返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。
这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
5、应用场景
对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。
实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。
1、引入缓存的jar包:ehcache-core-2.6.5.jar和mybatis-ehcache-1.0.2.jar
2、加入缓存配置文件ehcache.xml
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
3、修改mapper.xml中的
4、原理:
通过实现Cache接口可以实现mybatis缓存数据通过其它缓存数据库整合,mybatis的特长是sql操作,缓存数据的管理不是mybatis的特长,为了提高缓存的性能将mybatis和第三方的缓存数据库整合,比如ehcache、memcache、redis等
该博文主要介绍了mybatis的延迟加载,如何使用还有其应用场景;
介绍了一级缓存、二级缓存,并测试了一级二级缓存的使用范围,总结了二级缓存的使用场景;
整合了ehcahe的原因和原理。
如果有疑问或者对该博文有何看法或建议或有问题的,欢迎评论,恳请指正!