mybatis-高级结果映射之一对一(多种方式, 有没提到的你找我) (3)

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

可以看到, 上面的结果示意图中, 发送了两次 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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzyjg.html