在学习mybatis的延迟加载时,对 lazyLoadingEnabled 和 aggressiveLazyLoading 的区别并不理解,特别是对查询的条件不同时,执行的查询语句也不一样,所以还是测试总结一下
Blog: private Integer id; private String title; /*private Integer authorId;*/ private Author author; private String state; private Boolean featured; private String style; Author: private Integer id; private String username; private String password; private String email; private String bio; private String favouriteSection; private String nickname; private String realname;
测试用例如下:
1.1 使用默认配置,不查询任何属性
test:
@Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close(); System.out.println("查询结束"); }
console:
查询blog
Opening JDBC Connection
Created connection 1263877414.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
==> Preparing: select * from blog where id = ?
==> Parameters: 1(Integer)
====> Preparing: select * from author where id = ?
====> Parameters: 1(Integer)
<==== Total: 1
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Returned connection 1263877414 to pool.
查询结束
result:
使用默认的配置,并且不对blog进行任何属性的查询,但是仍然执行了对author表的查询
1.2 使用默认配置,查询blog的非author属性
test:
@Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close(); System.out.println("查询blog的title属性"); System.out.println(blog.getTitle());
System.out.println("查询结束"); }
console:
查询blog
Opening JDBC Connection
Created connection 1263877414.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
==> Preparing: select * from blog where id = ?
==> Parameters: 1(Integer)
====> Preparing: select * from author where id = ?
====> Parameters: 1(Integer)
<==== Total: 1
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Returned connection 1263877414 to pool.
查询blog的title属性
My Colourful Garden
查询结束
result:
使用默认配置,只对blog的非author属性进行查询,但是结果和test1.1一样,都执行了对author表的查询
1.3 使用默认配置,查询blog的属性(包括author属性)
test: @Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close(); System.out.println("查询blog的title属性"); System.out.println(blog.getTitle());
System.out.println("查询blog的author属性");
System.out.println(blog.getAuthor().getUsername());
System.out.println("查询结束"); } console: 查询blog Opening JDBC Connection Created connection 1263877414. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from blog where id = ? ==> Parameters: 1(Integer) ====> Preparing: select * from author where id = ? ====> Parameters: 1(Integer) <==== Total: 1 <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. 查询blog的title属性
My Colourful Garden
查询blog的author属性
helen 查询结束 result: 使用默认配置,对blog属性(包括author属性)进行查询,但是结果和test1.1以及test1.2一样,都执行了对author表的查询
2.1 配置 lazyLoadingEnabled:true; 不查询任何属性
config:
<!-- 延迟加载 默认不开启 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> </settings>
test:
@Test
public void testSelectBlogByIdLazyLoading() {
SqlSession session = MyBatisUtil.getSqlsession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
System.out.println("查询blog");
Blog blog = blogMapper.selectBlogById(1);
session.close();
System.out.println("查询结束"); }
console:
查询blog
Opening JDBC Connection
Created connection 1263877414.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
==> Preparing: select * from blog where id = ?
==> Parameters: 1(Integer)
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Returned connection 1263877414 to pool.
查询结束
result:
配置 lazyLoadingEnabled:true,并且不对blog进行任何属性查询,则session只执行对本表的查询
2.2 配置 lazyLoadingEnabled:true; 查询blog的非author属性
config: <!-- 延迟加载 默认不开启 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> </settings> test: @Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close();
System.out.println("查询blog的title属性");
System.out.println(blog.getTitle());
System.out.println("查询结束"); } console: 查询blog Opening JDBC Connection Created connection 1263877414. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from blog where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. 查询blog的title属性
Opening JDBC Connection
Checked out connection 1263877414 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
==> Preparing: select * from author where id = ?
==> Parameters: 1(Integer)
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26]
Returned connection 1263877414 to pool.
My Colourful Garden
查询结束 result: 配置 lazyLoadingEnabled:true,并且对blog进行非author查询,则session先执行对本表的查询,然后执行对author表的查询
2.3 配置 lazyLoadingEnabled:true;查询blog的属性(包括author属性)
config: <!-- 延迟加载 默认不开启 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> </settings> test: @Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close();
System.out.println("查询blog的title属性");
System.out.println(blog.getTitle());
System.out.println("查询blog的author属性");
System.out.println(blog.getAuthor().getUsername());
System.out.println("查询结束"); } console: 查询blog Opening JDBC Connection Created connection 1263877414. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from blog where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. 查询blog的title属性 Opening JDBC Connection Checked out connection 1263877414 from pool. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from author where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. My Colourful Garden
查询blog的author属性
helen 查询结束 result: 配置 lazyLoadingEnabled:true,并且对blog进行author查询,则结果和test2.2一样,session先执行对本表的查询,然后执行对author表的查询
3.1 配置lazyLoadingEnabled:true;aggressiveLazyLoading:false; 不查询任何属性
config:
<!-- 延迟加载 默认不开启 -->
<!-- 默认是积极的懒加载 -->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
test:
@Test
public void testSelectBlogByIdLazyLoading() {
SqlSession session = MyBatisUtil.getSqlsession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
System.out.println("查询blog");
Blog blog = blogMapper.selectBlogById(1);
session.close();
System.out.println("查询结束"); }
console:
查询blog Opening JDBC Connection Created connection 1263877414. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from blog where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. 查询结束
result:
配置 lazyLoadingEnabled:true,aggressiveLazyLoading:false; 并且不对blog进行任何查询,则session只执行对本表的查询
3.2 配置lazyLoadingEnabled:true;aggressiveLazyLoading:false; 查询非author属性
config: <!-- 延迟加载 默认不开启 -->
<!-- 默认是积极的懒加载 --> <settings> <setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/> </settings> test: @Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close();
System.out.println("查询blog的title属性");
System.out.println(blog.getTitle()); System.out.println("查询结束"); } console: 查询blog Opening JDBC Connection Created connection 1263877414. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from blog where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. 查询blog的title属性
My Colourful Garden 查询结束 result: 配置 lazyLoadingEnabled:true,aggressiveLazyLoading:false ;并且对blog进行非author查询,则session只执行对本表的查询
3.3 配置lazyLoadingEnabled:true;aggressiveLazyLoading:false; 查询blog的属性(包括author属性)
config: <!-- 延迟加载 默认不开启 -->
<!-- 默认是积极的懒加载 --> <settings> <setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/> </settings> test: @Test public void testSelectBlogByIdLazyLoading() { SqlSession session = MyBatisUtil.getSqlsession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); System.out.println("查询blog"); Blog blog = blogMapper.selectBlogById(1); session.close();
System.out.println("查询blog的title属性");
System.out.println(blog.getTitle());
System.out.println("查询blog的author属性");
System.out.println(blog.getAuthor().getUsername());
System.out.println("查询结束"); } console: 查询blog Opening JDBC Connection Created connection 1263877414. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from blog where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. 查询blog的title属性 Opening JDBC Connection Checked out connection 1263877414 from pool. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] ==> Preparing: select * from author where id = ? ==> Parameters: 1(Integer) <== Total: 1 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b553d26] Returned connection 1263877414 to pool. My Colourful Garden 查询blog的author属性 helen 查询结束 result: 配置 lazyLoadingEnabled:true;aggressiveLazyLoading:false; 并且对blog进行author查询,则session先执行对本表的查询,然后执行对author表的查询
在默认配置下,无论是否对blog的属性进行查询,session都会执行对blog表和对author表两条查询语句,然后存入缓存中,供查询结果调用,称为不延迟加载; 在配置lazyLoadingEnabled:true 后,如果不对blog的任何属性进行查询,session只会执行查询blog的语句;但是只要对blog的任意属性进行查询,就会查询blog表和author表,然后放入缓存,共查询结果调用,称为积极的延迟加载; 在配置 lazyLoadingEnabled:true;aggressiveLazyLoading:false;后,如果不对blog的author属性进行查询,session只会执行查询blog的语句;如果查询了blog的author属性,就会继续查询author,成为不积极的延迟加载
MyBatis的缓存机制:
参考链接:http://blog.csdn.net/luanlouis/article/details/41390801
MyBatis的缓存分为一级缓存和二级缓存
一级缓存是session级别的缓存,位于表示一次数据库会话的SqlSession对象之中,又被称为本地缓存;一级缓存是MyBatis内部实现的一个特性,用户不能配置,默认情况下自动支持的缓存,用户没有定制它的权利(可以通过开发插件对它进行修改)
二级缓存是Application应用缓存的缓存,它的生命周期很长,跟Application的声明周期一样,作用范围是整个Application应用