2020/04/22
最近在搞毕业论文、复试、spring,mybatis这两天没学。今天补更。。。
接上继续mybatis的级联查询。
2)一对多
所谓一对多,举个栗子来说,就是一个人只有一种id,但是可以有很多衣服、订单。同时这个订单表中都有一个属性项对应于唯一识别user的uid属性。
和一对一查询不一样,一对一中很大部分是通过外键来构成级联关系;一对多则不需要查询的表与表之间有这种外键约束(当然也可以有),直接通过某个唯一属性查询即可。
在mybatis中,一对多的关系通过<resultMap>标签中的<collection>标签来映射。
这种级联查询也分为三种方式:
①
<resultMap type="com.po.MyUser" id="userAndOrders1">
<id property="uid" column="uid" />
<result property="uname" column="uname" />
<result property="usex" column="usex" />
<!-- 一对多级联查询,ofType表示集合中的元素类型,将uid传递给selectOrdersByld -->
<collection property="orders" ofType="com.po.Orders"
column="uid" select="com.dao.OrdersDao.selectOrdersById" />
</resultMap>
<select id="selectUserOrdersById1" parameterType="Integer"
resultMap="userAndOrders1">
select * from user where uid = #{id}
</select>
---
从xml代码中可以看出,这种方式首先通过<select>标签中sql语句的执行,可以获得一个<resultMap>类型的返回对象,同时,在这个<resultMap>对象中以原参数(id)再进行一次查询(对应<collection>标签中的select属性,和一对一查询中的第一种方式类型),最后将两次查询拼凑起来形成一个以MyUser类型为元素的List对象。
需要注意的是,在<resultMap>标签中各种属性的定义必须和持久化的java对象属性一致,不然将报错。
可以看出这是一种内外嵌套查询方式。
②
<resultMap type="com.po.MyUser" id="userAndOrders2">
<id property="uid" column="uid" />
<result property="uname" column="uname" />
<result property="usex" column="usex" />
<!-- 对多级联查询,ofType表示集合中的元素类型 -->
<collection property="orders" ofType="com.po.Orders">
<id property="id" column="id" />
<result property="ordersn" column="ordersn" />
</collection>
</resultMap>
<select id="selectUserOrdersById2" parameterType="Integer"
resultMap="userAndOrders2">
select u.*,o.id, o.ordersn from user u, orders o where u.uid
= o.user_id and
u.uid=#{id}
</select>
---
这种方式与方式①异曲同工,而差别就在于<collection>标签的配置以及<select>标签中sql语句的不同。
首先,<collection>标签中与方法①中实际上是一样的,都是传递参数形成一个Orders持久化对象,只是在这里没有select属性来再进行内查询而已(因为下面的<select>标签中做了)。
接下来剖析<select>标签。这里的<select>标签中是自然连接查询(①中是内外嵌套查询),查询后直接形成了两个表的笛卡尔积的形式,因此在<resultMap>标签中可以直接配置属性传递。
③
<!-- 一对多 根据uid查询用户及其关联的订单信息:连接查询(使用POJO存储结果) -->
<select id="selectUserOrdersById3" parameterType="Integer"
resultType="com.po.SelectUserOrdersById">
select u.*, o.id, o.ordersn from user u, orders o where
u.uid = o.user_id
and u.uid=#{id}
</select>
---
方式③直接对两个表进行自然连接再查询,并且使用POJO来存储查询结果。这种方式与上面两种的不同之处在于,这种方式需要重新定义一个持久化对象(如本例的SelectUserOrdersById。class)。
而在上面两种方法中,由于是使用MyUser类型存储查询结果,因此只需要在一对一查询的基础在MyUser类添加一个Orders属性即可。