前兩節(jié)說(shuō)到了一對(duì)一漆际、一對(duì)多和多層級(jí)聯(lián)操作淆珊,當(dāng)多層級(jí)聯(lián)層數(shù)太多時(shí),不建議使用級(jí)聯(lián)奸汇,會(huì)造成復(fù)雜度的增加施符,不利于他人的理解和維護(hù)楞陷,同時(shí)還存在一些劣勢(shì)璧微,比如有時(shí)候并不需要獲取所有的數(shù)據(jù),吩翻,但是級(jí)聯(lián)會(huì)多執(zhí)行幾次SQL婴洼,將全部關(guān)聯(lián)信息查詢出來(lái)骨坑,這樣就會(huì)導(dǎo)致執(zhí)行SQL較多從而導(dǎo)致性能下降。針對(duì)這種問(wèn)題,我們可以使用延遲加載來(lái)解決欢唾,本節(jié)繼續(xù)使用前兩節(jié)的demo來(lái)演示延遲加載的功能且警。
- 全局配置
- 修改application.yml 添加延遲加載全局配置
mybatis:
mapper-locations: classpath:mappers/*.xml
configuration:
#開(kāi)啟延遲加載,默認(rèn)即時(shí)加載
lazy-loading-enabled: true
#Mybatis默認(rèn)是按層級(jí)延遲加載的礁遣,為true時(shí)按層級(jí)加載斑芜,否則就按我們調(diào)用的要求加載
aggressive-lazy-loading: false
#打印日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#指定哪個(gè)對(duì)象的方法觸發(fā)一次延遲加載。默認(rèn)值:equals,clone,hashCode,toString 祟霍,可以阻擋不相干的操作觸發(fā)杏头,實(shí)現(xiàn)懶加載
lazy-load-trigger-methods: ""
注意:實(shí)體類中如果是使用的lombok,則加上@ToString(doNotUseGetters = true)
- 修改AuthorService沸呐,方便查看效果
@Service
public class AuthorService {
@Autowired
private AuthorMapper authorMapper;
public Author getAuthorById(String id) {
Author author = authorMapper.getAuthorById(id);
System.out.println("查詢作者信息表數(shù)據(jù)");
author.getAuthorInformation();
System.out.println("查詢作者的主題表數(shù)據(jù)");
author.getSpecials();
System.out.println("查詢作者的文章表數(shù)據(jù)");
for (int i = 0; i < author.getSpecials().size(); i++) {
author.getSpecials().get(i).getArticles();
}
return author;
}
}
測(cè)試
在第一步打個(gè)斷點(diǎn)醇王,然后調(diào)用AuthorService的getAuthorById方法獲取作者信息第一步執(zhí)行結(jié)束后可以看到級(jí)聯(lián)的authorInformation和specials信息沒(méi)有查詢出來(lái),級(jí)聯(lián)的SQL也沒(méi)有執(zhí)行崭添。
- 局部配置
也有部分場(chǎng)景屁置,需要一部分級(jí)聯(lián)的對(duì)象數(shù)據(jù)即時(shí)加載焊夸,一部分不需要,這個(gè)時(shí)候可以使用局部延遲加載的功能蓝角,我們可以在
association
和collection
元素中加入fetchType
屬性實(shí)現(xiàn)局部延遲加載功能阱穗。
fetchType
有兩個(gè)取值,如下:
eager
:即時(shí)加載
lazy
:延遲加載
- 修改AuthorMapper.xml帅容,為association添加
fetchType="eager"
實(shí)現(xiàn)即時(shí)加載颇象,為collection 添加fetchType="lazy"
實(shí)現(xiàn)延遲加載
<resultMap id="BaseResultMap" type="com.sy.mybatis.pojo.Author" >
<id column="id" property="id" jdbcType="VARCHAR" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="login_name" property="loginName" jdbcType="VARCHAR" />
<result column="pwssword" property="pwssword" jdbcType="VARCHAR" />
<association fetchType="eager" property="authorInformation" column="id" select="com.sy.mybatis.mapper.AuthorInformationMapper.getAuthorInformationbyAuthorId"></association>
<collection fetchType="lazy" property="specials" column="id" select="com.sy.mybatis.mapper.SpecialMapper.getSpecialsByAuthorId"></collection>
</resultMap>
測(cè)試
在第一步打個(gè)斷點(diǎn)伍伤,然后調(diào)用AuthorService的getAuthorById方法獲取作者信息
fetchType="eager"
即時(shí)加載級(jí)聯(lián)的authorInformation對(duì)象數(shù)據(jù)查詢了出來(lái)并徘,執(zhí)行了級(jí)聯(lián)SQL,而設(shè)置了fetchType="lazy"
延遲加載的specials對(duì)象信息沒(méi)有查詢出來(lái)扰魂,級(jí)聯(lián)的SQL也沒(méi)有執(zhí)行麦乞。
在return處再打個(gè)斷點(diǎn),繼續(xù)執(zhí)行代碼到return處劝评。從執(zhí)行的sql日志中可以看到姐直,再次調(diào)用即時(shí)加載的屬性時(shí)沒(méi)有重新執(zhí)行級(jí)聯(lián)查詢,后面的延遲加載對(duì)象在我調(diào)用時(shí)才去查詢了對(duì)應(yīng)的數(shù)據(jù)蒋畜,這樣就實(shí)現(xiàn)了局部延遲加載功能声畏。