在這之前我們知道了MyBatis為我們提供了三種級聯:一對一關系(assocation)、一對多關系(collection)、鑒別器(discriminator)。在最后一個鑒別器例子中,看到了當層級關系比較負責時,我們似乎已經難以應對和維護各種級聯關系,在對數據庫進行查詢是否應用MyBatis為我們提供的級聯這需要在實際中去斟酌和取舍。在我們通過級聯來查詢信息時會發現有一個問題,當我們只想查詢出學生的普通信息(姓名、性別),而不想查詢出他的成績、課程、體檢表時,之前的三個例子不管你是否需要成績、課程等信息它都會去執行,只要有一個關聯。這並不是我們所想要的,我們所想要的是,我需要時才去執行這條sql,我需要成績時才將此條sql發送到數據庫查詢出結果,不需要時就不需要發送到數據庫進行查詢。很高興的是,MyBatis為我們提供了這一需求,即:lazyLoadingEnabled。
我們在mybatis-config.xml配置文件中做一下配置:
<settings> <setting name="lazyLoadingEnabled" value="true"/><!-- 開啟懶加載模式(按需加載),默認情況下是即時加載 --> </settings>
這句話的意思就是我們上面所要想達到的效果——按需加載。但其實只有這么一句話是不夠的,MyBatis的延遲加載方式是按層級延遲加載。
當我們在查詢學生的基本信息時,MyBatis會根據鑒別器去找到健康情況。而在當我們訪問課程成績時,由於學生證和課程成績出於同一層級,所以學生證也會跟着被加載。只有課程不是和課程成績出於同一層級,所以它不會被加載。這還沒有達到我們想要的“按需加載”效果,我們所想要達到的按需加載是真正只有用到的時候才會去加載。這個時候就需要在剛剛的配置文件中再做以下的配置:
<settings> <setting name="lazyLoadingEnabled" value="true"/><!-- 開啟懶加載模式(按需加載),默認情況下是即時加載 --> <setting name="aggressiveLazyLoading" value="false"/>
</settings>
attressiveLazyLoading配置項,意思就是這個意思——侵略性延遲加載。
這實際上是在mybatis-config.xml文件中做的全局配置,當想要針對某些屬性進行延遲加載,對某些屬性進行立即加載時,我們可以細化到具體的mapper映射配置文件中去。例如StudentMapper.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="day_8_mybatis.mapper.StudentMapper"> 6 <resultMap type="day_8_mybatis.pojo.Student" id="studentMap"> 7 <id property="id" column="id"/> 8 <result property="name" column="name"/> 9 <result property="sex" column="sex"/> 10 <association property="selfCard" column="id" select="day_8_mybatis.mapper.SelfCardMapper.findSelfCardByStudentId" fetchType="lazy"/> 11 <collection property="courseScoreList" column="id" select="day_8_mybatis.mapper.CourseScoreMapper.findCourseScoreByStudentId" fetchType="eager"/> 12 <discriminator javaType="string" column="sex"> 13 <case value="男" resultMap="maleStudentMap"/> 14 <case value="女" resultMap="femaleStudentMap"/> 15 </discriminator> 16 </resultMap> 17 <!--以下省略-->
在第10行中我們對查詢出學生的學生證信息配置為延遲加載,第11行中我們對查詢出學生的課程成績做了立即加載配置。
以上幾乎就是MyBatis級聯的全部內容,至於用級聯還是用sql的join語句只有在實際中去認真仔細考量和權衡。