Mybatis学习总结第四课----关联查询(两种关联查询方式)

mac2024-03-22  29

        在关系型数据库中,我们经常要处理一对一 、 一对多的关系 。 例如, 一辆汽车需要有一个引擎,这是一对一的 关系。 一辆汽车有 4 个或更多个轮子,这是一对多的关系 。关联元素就是专门用来处理关联关系的。

在java类中关联关系也有三种,一对一,一对多,多对多     一对一   在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a    一对多   一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a    多对多   在A类中定义B类类型的集合,在B类中定义A类类型的集合  

   一 、两种关联方式

     嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集      嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型

        对于嵌套查询可以使用懒加载方法实现优化

   *Mybatis的延迟加载配置

   在全局配置文件中加入下面代码

<settings> <setting name="lazyLoadingEnabled" value="true" /> <setting name="aggressiveLazyLoading" value="false"/> </settings>

   在映射文件中,<association>元素和<collection>元素中都已默认配置了延迟加载属性,即默认属性fetchType="lazy"(属性fetchType="eager"表示立即加载),所以在配置文件中开启延迟加载后,无需在映射文件中再做配置

 

二 、具体分析

   2.1 一对一关系查询  <association>标签

      使用<association>元素进行一对一关联映射非常简单,只需要参考如下两种示例配置即可

            

下面使用一个例子来验证。有两个对象,一个为员工、一个为职位。员工对象中包含职位 为一对一关系。

public class TUser { private Integer id; private String userName; private String realName; private Byte sex; private String mobile; private String email; private String note; private Integer positionId; //职位 private TPosition position; } public class TPosition { private Integer id; //职位 private String postName; private String note; }

嵌套结果

<resultMap id="BaseResultMap" type="com.study.mybatis.entity.TUser"> <id column="id" property="id" jdbcType="INTEGER" /> <result column="user_name" property="userName" jdbcType="VARCHAR" /> <result column="real_name" property="realName" jdbcType="VARCHAR" /> <result column="sex" property="sex" jdbcType="TINYINT" /> <result column="mobile" property="mobile" jdbcType="VARCHAR" /> <result column="email" property="email" jdbcType="VARCHAR" /> <result column="note" property="note" jdbcType="VARCHAR" /> <result column="position_id" property="positionId" jdbcType="INTEGER" /> </resultMap> <resultMap id="userAndPosition1" extends="BaseResultMap" type="com.study.mybatis.entity.TUser"> <association property="position" javaType="TPosition" > <id column="post_id" property="id"/> <result column="post_id" property="postName"/> <result column="post_note" property="note"/> </association> </resultMap> <select id="selectUserPosition1" resultMap="userAndPosition1"> select a.id,user_name,real_name,sex,mobile,email,a.note,a.position_id ,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="userAndPosition2" extends="BaseResultMap" type="com.study.mybatis.entity.TUser"> <association property="position" column="position_id" fetchType="lazy" select="com.study.mybatis.mapper.TPositionMapper.selectByPrimaryKey"> </association> </resultMap> <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>

                      

2.2  collection 一对多关系

<resultMap>元素中,包含了一个<collection>子元素,MyBatis就是通过该元素来处理一对多关联关系的

<collection>子元素的属性大部分与<association>元素相同,但其还包含一个特殊属性--ofType

ofType属性与javaType属性对应,它用于指定实体对象中集合类属性所包含的元素类型。

<collection >元素的使用也非常简单,同样可以参考如下两种示例进行配置,具体代码如下:           

   嵌套结果    

<resultMap id="userAndJobs1" extends="BaseResultMap" type="TUser"> <collection property="jobs" ofType="com.enjoylearning.mybatis.entity.TJobHistory" > <result column="comp_name" property="compName" jdbcType="VARCHAR" /> <result column="years" property="years" jdbcType="INTEGER" /> <result column="title" property="title" jdbcType="VARCHAR" /> </collection> </resultMap> <select id="selectUserJobs1" resultMap="userAndJobs1"> select a.id,a.user_name,a.real_name,a.sex,a.mobile,b.comp_name,b.years,b.title from t_user a,t_job_history b where a.id = b.user_id </select>

嵌套查询

<resultMap id="userAndJobs2" extends="BaseResultMap" type="TUser"> <collection property="jobs" fetchType="lazy" column="id" select="com.study.mybatis.mapper.TJobHistoryMapper.selectByUserId" /> </resultMap> <select id="selectUserJobs2" resultMap="userAndJobs2"> select a.id,a.user_name,a.real_name,a.sex, a.mobilefrom t_user a </select>

    

2.3 多对多 

多对多的关联关系查询,同样可以使用前面介绍的<collection >元素进行处理(其用法和一对多关联关系查询语句用法基本相同)

<resultMap type="TUser" id="userRoleInfo" extends="BaseResultMap"> <collection property="roles" ofType="TRole" columnPrefix="role_"> <result column="id" property="id" /> <result column="Name" property="roleName" /> <result column="note" property="note" /> </collection> </resultMap> <select id="selectUserRole" resultMap="userRoleInfo"> select a.id,a.user_name,a.real_name,a.sex,a.mobile,a.note,b.role_id,c.role_name,c.note role_note from t_user a, t_user_role b,t_role c where a.id = b.user_id AND b.role_id = c.id </select>

2.4 discriminator 鉴别器映射

      在特定的情况下使用不同的pojo进行关联, 鉴别器元素就是被设计来处理这个情况的。鉴别器非常容易理解,因为它 的表现很像 Java 语言中的 switch 语句

 discriminator 标签常用的两个属性如下:  column:该属性用于设置要进行鉴别比较值的列 。  javaType:该属性用于指定列的类型,保证使用相同的 Java 类型来比较值。     discriminator 标签可以有1个或多个 case 标签, case 标签包含以下三个属性 。        value : 该值为 discriminator 指定 column 用来匹配的值 。      resultMap : 当column的值和value的值匹配时,可以配置使用resultMap指定的映射,resultMap优先级高于 resultType       resultType : 当 column 的值和 value 的值匹配时,用于配置使用 resultType指定的映射。 <resultMap id="userAndHealthReportMale" extends="userAndHealthReport" type="TUser"> <collection property="healthReports" column="id" select= "com.study.mybatis.mapper.THealthReportMaleMapper.selectByUserId"></collection> </resultMap> <resultMap id="userAndHealthReportFemale" extends="userAndHealthReport" type="TUser"> <collection property="healthReports" column="id" select= "com.study.mybatis.mapper.THealthReportFemaleMapper.selectByUserId"></collection> </resultMap> <resultMap id="userAndHealthReport" extends="BaseResultMap" type="TUser"> <discriminator column="sex" javaType="int"> <case value="1" resultMap="userAndHealthReportMale"/> <case value="2" resultMap="userAndHealthReportFemale"/> </discriminator> </resultMap> <select id="selectUserHealthReport" resultMap="userAndHealthReport"> select <include refid="Base_Column_List" /> from t_user a </select>

 

最新回复(0)