一、背景
记上篇文章订单与用户之间的关系属于一对一关系,本文我们分析一对多关系。一个用户可以下多个订单,所以用户与订单的关系是一对多。
二、一对多
需求:查询所有用户信息及用户关联的订单信息。
继上篇 Mybatis 关联查询之一对一查询中,我们改变了原有的Order类,加入User 属性,所以在这里我们将改变User类,加入Order 属性。
// 一对多
private List<Order> order;
查询所有用户信息,以用户表为主,同时还要求查询与之关联的订单信息,所以我们就需要通过映射来书写sql语句。
接下来我们编写 Mapper.xml 和 Mapper 接口文件
<resultMap type="User" id="UserOrderMap">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
<result property="address" column="address"/>
<!--一对多,用户表为中心,关联订单表-->
<collection property="order" javaType="list" ofType="Order">
<!-- 配置主键,是关联Order的唯一标识,次数columu使用了别名 -->
<id property="id" column="oid"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<select id="queryUserOrder" resultMap="UserOrderMap">
select
u.id,
u.username,
u.sex,
u.birthday,
u.address,
o.id oid,
o.number,
o.createtime,
o.note
from user u left join orders o
on u.id = o.user_id
</select>
以用户表为主,关联订单表 ,一对多,所以使用 collection 标签,其中 property 表示与用户表关联订单表的属性,javaType 表示这个属性的 java 类型,ofType 表示 这个类型是什么类型的对象。使用了ResultMap 属性,通过映射将订单信息返回。
// 查询所有用户信息及用户关联的订单信息
public List<User> queryUserOrder();
测试:
@Test
public void queryUserOrder() throws Exception {
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("sqlMapConfig.xml"));
SqlSession session = sqlSessionFactory.openSession();
OrderMapper orderMapper = session.getMapper(OrderMapper.class);
List<User> list = orderMapper.queryUserOrder();
for (User user : list) {
System.out.println(user);
}
}
根据结果显示,在返回的User对象中,封装了Order对象,将该用户下的订单全部查询出来。
总结:订单表属于多的一方,有外键字段 user_id 指向一的一方,即user表中的主键id。我们必须弄清楚,集合类型要加到一的一方,而多的一方加入关联的对象即可。这样根据需求通过sql 语句编写 Mapper.xml 时,也会明确很多。