在关系型数据库中,我们经常要处理一对一 、 一对多的关系 。 例如, 一辆汽车需要有一个引擎,这是一对一的
关系。 一辆汽车有 4 个或更多个轮子,这是一对多的关系 。关联元素就是专门用来处理关联关系的;
关联元素
association 一对一关系
collection 一对多关系
discriminator 鉴别器映射
关联方式
嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型
实体属性:private TPosition position;
一对一 嵌套结果
association标签 嵌套结果方式 常用属性:
property :对应实体类中的属性名,必填项。
javaType : 属性对应的 Java 类型 。
resultMap : 可以直接使用现有的 resultMap ,而不需要在这里配置映射关系。
columnPrefix :查询列的前缀,配置前缀后,在子标签配置 result 的 column 时可以省略前缀
示例代码:
<select id="selectUserPosition1" resultMap="userAndPosition1">
select
a.id,
user_name,
real_name,
sex,
mobile,
email,
a.note,
b.id post_id,
b.post_name,
b.note post_note
from t_user a,
t_position b
where a.position_id = b.id
</select>
<resultMap id="userAndPosition1" extends="BaseResultMap" type="TUser">
<association property="position" javaType="TPosition" columnPrefix="post_">
<id column="id" property="id"/>
<result column="name" property="postName"/>
<result column="note" property="note"/>
</association>
</resultMap>
一对一 嵌套查询
association标签 嵌套查询方式 常用属性:
select :另 一个映射查询的 id, MyBatis 会额外执行这个查询获取嵌套对象的结果 。
column :列名(或别名),将主查询中列的结果作为嵌套查询的 参数。
fetchType :数据加载方式,可选值为 lazy 和 eager,分别为延迟加载和积极加载 ,这个配置会覆盖全
局的 lazyLoadingEnabled 配置;
示例代码:
<select id="selectUserPosition2" resultMap="userAndPosition2">
select
a.id,
a.user_name,
a.real_name,
a.sex,
a.mobile,
a.position_id
from t_user a
</select>
<resultMap id="userAndPosition2" extends="BaseResultMap" type="TUser">
<association property="position" fetchType="lazy" column="position_id" select="com.caojiulu.mybatis.mapper.TPositionMapper.selectByPrimaryKey" />
</resultMap>
Tips:“N+1 查询问题”
概括地讲,N+1 查询问题可以是这样引起的:
你执行了一个单独的 SQL 语句来获取结果列表(就是“+1”)。
对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。
这个问题会导致成百上千的 SQL 语句被执行。这通常不是期望的。
解决办法:使用“fetchType=lazy”并且全局setting进行改善:
<setting name= "aggressiveLazyLoading" value="false"/>