fetchType: 数据加载的方式, 可选择为 lazy(延迟加载) 或者 eager(积极加载), 该配置会覆盖全局的 lazyLoadingEnabled 配置。
2.5.3 创建接口方法和XML 语句 /** * 根据博客的 id 获取博客及作者的信息, resultMap + association嵌套方式 * @param id * @return */ BlogCustom selectBlogAndAuthorByIdSelect(int id);获取的数据是博客和用户的信息, 以下的 SQL 只是获取博客信息, 用户信息通过 com.homejim.mybatis.mapper.AuthorMapper.selectById 获取。
<select parameterType="java.lang.Integer" resultMap="blogAuthorMap"> SELECT b.id, b.title, b.author_id FROM blog b where b.id = #{id,jdbcType=INTEGER} </select>com.homejim.mybatis.mapper.AuthorMapper.selectById 是一个全限定名, 即 AuthorMapper 下的 selectById 方法
/** * 嵌套查询使用的方法 * @param id * @return */ Author selectById(Integer id);对应的 SQL
<select parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from author where id = #{id} </select> 2.5.4 测试使用时, 调用 selectBlogAndAuthorByIdSelect 方法即可。
/** * resultMap + association 嵌套查询方式测试 */ @Test public void testSelectBlogAndAuthorByIdSelect() { SqlSession sqlSession = sqlSessionFactory.openSession(); BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); BlogCustom blogCustom = blogMapper.selectBlogAndAuthorByIdSelect(1); System.out.println(ToStringBuilder.reflectionToString(blogCustom, ToStringStyle.MULTI_LINE_STYLE)); Assert.assertNotNull(blogCustom); Assert.assertNotNull(blogCustom.getAuthor()); }输出, 会发送两次 SQL 语句。
可以看到, 上面的结果示意图中, 发送了两次 SQL 。
2.5.5 延迟加载如果是一个对象中只是包含一两个对象, 使用上面的方式还好。 但是如果包含有很多, 那要一次性发送很多次 SQL, 性能上就会很有影响。延迟加载可以解决此类的问题。
延迟加载就是说,只有在调用内部的对象时, 才会把获取该对象的 SQL 发送出去。
更改结果集
<resultMap type="com.homejim.mybatis.entity.BlogCustom" extends="BaseResultMap"> <association fetchType="lazy" property="author" column="author_id" select="com.homejim.mybatis.mapper.AuthorMapper.selectById" /> </resultMap>将上面的查询中的结果集更改 resultMap="blogAuthorMapLazy"
<select parameterType="java.lang.Integer" resultMap="blogAuthorMapLazy"> <!--resultMap="blogAuthorMap"--> SELECT b.id, b.title, b.author_id FROM blog b where b.id = #{id,jdbcType=INTEGER} </select>更改延迟加载总开关
<setting value="true"/> <setting value="false"/>测试
注意: 延迟加载是在 SqlSession 的声明周期内的, 如果超出该声明周期, 如 spring 中, 只能在 Service 层使用延迟加载的对象, 如果返回Controller层在获取延迟加载属性, 则会抛出异常。
有时候, 我们配置了延迟加载, 但是却想要一次性加载, 怎么办?
有一个配置属性可以帮我们解决 lazyLoadTriggerMethods, 它的默认配置如下:
<setting value="equals,clone,hashCode,toString"/>就是说我们使用上面配置中的任何一个方法(上面的是默认的, 我们可以不配置), 就可以加载属性啦。
测试
/** * resultMap + association 嵌套查询方式测试(延迟加载不延迟lazyLoadTriggerMethods) */ @Test public void testSelectBlogAndAuthorByIdSelectTrigger() { SqlSession sqlSession = sqlSessionFactory.openSession(); BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); BlogCustom blogCustom = blogMapper.selectBlogAndAuthorByIdSelect(1); blogCustom.equals(null); Assert.assertNotNull(blogCustom); sqlSession.close(); System.out.println("开始使用author对象"); Assert.assertNotNull(blogCustom.getAuthor()); }结果
3. 代码本来还要写的一对多, 鉴别器的, 但由于篇幅的原因, 后续继续吧。
我的 Github:mybatis-mapping