首页 > 代码库 > MyBatis应用开发(17)延迟加载之应用
MyBatis应用开发(17)延迟加载之应用
1.1.1. 没有使用延迟加载的情况
在没有进行任何特定配置的情况下MyBatis默认是关闭了延迟加载功能,即使用立即加载。
在SqlMapConfig.xml中确认关闭了延迟加载功能。
<!-- 延迟加载:true, 立即加载:false,默认false --> <setting name="lazyLoadingEnabled" value="false" /> <!-- 侵略性延迟加载 : 默认false(3.4.2以及更新版本MyBatis) true:访问代理对象任何方法将导致关联对象被立即加载。此时导致lazyLoadingEnabled失效。 false:关联对象不会被立即加载。 --> <setting name="aggressiveLazyLoading" value="false" /> <!-- 在使用延迟加载之后,访问代理对象的哪些方法将导致加载被触发 默认值:equals,clone,hashCode,toString。 --> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
Mapper配置:
在association或collection中关闭确认关闭了延迟加载功能:
显式的使用fetchType="eager"或者不定义fetchType属性。
<!-- 主表resultMap --> <resultMap type="com.test.mybatis3.pojo.Person" id="personResultMap"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="status" column="status" /> <!-- Person通过idCard属性导航到IdCard --> <association property="idCard" column="id" javaType="com.test.mybatis3.pojo.IdCard" fetchType="eager" select="findIdCardByPersonId"> </association> </resultMap> <!-- 子表resultMap:IdCard的映射 --> <resultMap type="com.test.mybatis3.pojo.IdCard" id="idCardResultMap"> <id property="cardid" column="cardid" /> <result property="personid" column="personid" /> </resultMap> <!-- 主表查询 --> <select id="findAllPersons" resultMap="personResultMap"> select * from t_person </select> <!-- 子表查询 --> <select id="findIdCardByPersonId" parameterType="string" resultMap="idCardResultMap" > select * from t_idcard where personid=#{id} </select>
Mapper接口的方法:
List<Person> findAllPersons() throws Exception;
单元测试代码:
//打开Session。 session = sessionBuilder.openSession(); //找到MyBatis自动实现的PersonMapper接口的代理对象。 PersonMapper personMapper = session.getMapper(PersonMapper.class); //嵌套查询。 List<Person> persons = personMapper.findAllPersons(); System.out.println("---------------------"); //输出查询结果。 for(Person person : persons){ System.out.println(person.getId() +","+person.getName()); } System.out.println("---------------------"); for(Person person : persons){ IdCard idCard = person.getIdCard(); System.out.println("================"); System.out.println(idCard); }
运行结果:
0 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Preparing: select * from t_person
47 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Parameters:
70 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Columns: id, name, status
70 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Row: lisi, li si, 0
73 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ====> Preparing: select * from t_idcard where personid=?
73 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ====> Parameters: lisi(String)
76 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <==== Columns: personid, cardid
76 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <==== Row: lisi, 222222222222222222
76 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <==== Total: 1
77 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Row: zhangsan, zhang san, 0
77 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ====> Preparing: select * from t_idcard where personid=?
78 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ====> Parameters: zhangsan(String)
79 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <==== Columns: personid, cardid
79 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <==== Row: zhangsan, 1111111111111111
79 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <==== Total: 1
79 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Total: 2
---------------------
lisi,li si
zhangsan,zhang san
---------------------
================
IdCard [cardid=222222222222222222, personid=lisi, person=null]
================
IdCard [cardid=1111111111111111, personid=zhangsan, person=null]
从运行结果可以看到,在执行findAllPersons()方法时,不仅执行了查询Person的SQL,而且执行了查询IdCard的SQL。也就是查询Person时,立即执行了查询关联对象的SQL。
1.1.2. 使用延迟加载的情况
在前面没有使用延迟加载的例子中,对Mapper配置进行修改。按照前面介绍的延迟加载方法二(即修改fetchType为lazy)进行修改。
<!-- 主表resultMap --> <resultMap type="com.test.mybatis3.pojo.Person" id="personResultMap"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="status" column="status" /> <!-- Person通过idCard属性导航到IdCard --> <!-- 将fetchType修改为延迟加载 --> <association property="idCard" column="id" javaType="com.test.mybatis3.pojo.IdCard" fetchType="lazy" select="findIdCardByPersonId"> </association> </resultMap> <!-- 子表resultMap:IdCard的映射 --> <resultMap type="com.test.mybatis3.pojo.IdCard" id="idCardResultMap"> <id property="cardid" column="cardid" /> <result property="personid" column="personid" /> </resultMap> <!-- 主表查询 --> <select id="findAllPersons" resultMap="personResultMap"> select * from t_person </select> <!-- 子表查询 --> <select id="findIdCardByPersonId" parameterType="string" resultMap="idCardResultMap" > select * from t_idcard where personid=#{id} </select>
执行同样的单元测试代码,运行结果如下:
Tue Apr 25 21:49:32 CST 2017 WARN: Establishing SSL connection without server‘s identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn‘t set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to ‘false‘. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
0 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Preparing: select * from t_person
44 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Parameters:
67 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Columns: id, name, status
67 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Row: lisi, li si, 0
164 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Row: zhangsan, zhang san, 0
166 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Total: 2
---------------------
lisi,li si
zhangsan,zhang san
---------------------
166 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ==> Preparing: select * from t_idcard where personid=?
168 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ==> Parameters: lisi(String)
169 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <== Columns: personid, cardid
170 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <== Row: lisi, 222222222222222222
171 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <== Total: 1
================
IdCard [cardid=222222222222222222, personid=lisi, person=null]
171 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ==> Preparing: select * from t_idcard where personid=?
171 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - ==> Parameters: zhangsan(String)
171 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <== Columns: personid, cardid
171 [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <== Row: zhangsan, 1111111111111111
173 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByPersonId - <== Total: 1
================
IdCard [cardid=1111111111111111, personid=zhangsan, person=null]
观察运行结果可以发现,在执行findAllPersons()方法时,仅仅执行了查询Person的SQL语句,而没有执行查询IdCard的SQL语句。当执行IdCard idCard = person.getIdCard();时才执行查询IdCard的SQL语句。
MyBatis应用开发(17)延迟加载之应用