Mybatis collection 一对多查询 Mybat

Mybatis collection

需求

1
2
3
4
5
复制代码查询所有用户信息及用户关联的订单信息。

主信息:用户信息

从信息:订单信息

分析

在一对多关联查询时,只能使用resultMap进行结果映射。
1、一对多关联查询时,sql查询结果有多条,而映射对象是一个。
2、resultType完成结果映射的方式的一条记录映射一个对象。
3、resultMap完成结果映射的方式是以[主信息]为主对象,[从信息]映射为集合或者对象,然后封装到主对象中。

po类

PO 用户订单列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
arduino复制代码@Data
public class UserOrderList {


/**
* 用户ID
*/
private int id;

/**
* 用户名称
*/
private String username;

/**
* 生日
*/
private Date birthday;

/**
* 性别
*/
private String sex;

/**
* 地址
*/
private String address;

/**
* 创建时间
*/
private Long createTime;

/**
* 订单列表
*/
private List<Order> orders;
}

注:PO类不能使用extends赋值不进去

UserMapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
java复制代码public interface UserMapper {

/**
* 获取用户订单列表
* @param userId string 用户ID
* @return
*/
UserOrderList getUserOrderList(int userId);

/**
* 获取用户订单列表
* @param userId string 用户ID
* @return
*/
UserOrderList getOrderListByUserId(int userId);

}

UserMapper.xml

分布查询

resultMap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
xml复制代码<!-- 一对多 分布查询 -->
<resultMap id="selectOrderByUser" type="com.xxx.www.mybatis.phase04.po.UserOrderList">
<!-- 用户信息映射 -->
<!-- column 数据库字段 | property 映射po类的字段名 -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<result column="create_time" property="createTime"/>

<!-- 一对多 订单关联属性映射:使用select引用方式 -->
<!-- collection定义关联集合类型的属性的封装规则 -->
<!-- property: 对应po类关联的集合字段 orders -->
<!-- column: 关联字段 与sql查询结果的字段对应 -->
<!-- ofType: 指定的是映射到list集合属性中的pojo类型 -->
<!-- fetchType: 加载类型:lazy(延迟加载)eager(立即加载)如果使用,它将取代全局配置参数lazyLoadingEnable -->
<!-- select 分布查询引用 引用的方法 -->
<collection property="orders" column="id" ofType="com.xxx.www.mybatis.phase04.po.Order" select="com.xxx.www.mybatis.phase04.mapper.OrderMapper.selectOderByUserId" fetchType="lazy">
</collection>

</resultMap>
查询sql
1
2
3
4
5
6
7
8
9
10
11
xml复制代码 <!-- 查询用户订单列表 一对多 -->
<select id="getUserOrderList" resultMap="selectOrderByUser" parameterType="int">
SELECT
id, username, birthday, sex, address, create_time
FROM
`user` u
<if test="userId != null ">
where
u.id = #{userId}
</if>
</select>

连表单词查询

resultMap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
xml复制代码<!-- 一对多 链表查询 -->
<resultMap id="selectOrderListByUserId" type="com.xxx.www.mybatis.phase04.po.UserOrderList">
<!-- 用户信息映射 -->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!-- 一对多 订单信息映射 -->
<collection property="orders" ofType="com.xxx.www.mybatis.phase04.po.Order">
<id column="order_id" property="orderId"/>
<result column="order_number" property="orderNumber"/>
<result column="user_id" property="userId"/>
<result column="prepayment_amount" property="prepaymentAmount"/>
<result column="actually_paid_amount" property="actuallyPaidAmount"/>
<result column="create_time" property="createTime"/>
<result column="goods_kind" property="goodsKind"/>
<result column="goods_quantity" property="goodsQuantity"/>
<result column="payment_method" property="paymentMethod"/>
<result column="trade_on" property="tradeOn"/>
<result column="price_after_discount" property="priceAfterDiscount"/>
</collection>
</resultMap>
查询sql
1
2
3
4
5
6
7
8
9
10
11
12
13
xml复制代码<!-- 查询用户订单列表 一对多 -->
<select id="getOrderListByUserId" resultMap="selectOrderListByUserId">
SELECT
u.id AS user_id, u.username, u.birthday, u.sex, u.address, o.id AS order_id, o.user_id, u.create_time, o.order_number, o.create_time, o.prepayment_amount, o.actually_paid_amount, o.goods_kind, o.goods_quantity, o.payment_method, o.trade_on, o.price_after_discount
FROM
`user` AS u
JOIN
`order` AS o
where
u.id = o.user_id
and
u.id = #{userId}
</select>

注: 如果两表联查,主表和明细表的主键都是id的话,明细表的多条只能查询出来第一条。
u.id AS user_id 和 o.id AS order_id,直接都用 id 查询多条,得到结果为一条

测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
scss复制代码public class Phase04Test {

/**
* mybatis mysql连接器
*/
private SqlSessionFactory sqlSessionFactory;

private SqlSession sqlSession;

@Before
public void init() throws Exception {
// 加载全局配置文件(同时把映射文件也加载了)
String resource = "phase04/SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// sqlsessionFactory需要通过sqlsessionFactoryBuilder读取全局配置文件信息之后
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//创建UserMapper对象
sqlSession = sqlSessionFactory.openSession();
}

@Test
public void testFindOrderById() {
// 获取代理对象
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List<OrderExt> orderExtList = mapper.selectOrderAndUserInfo();
System.out.println(orderExtList);
}

@Test
public void getOrderByUserId() {
// 获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserOrderList orderList = mapper.getUserOrderList(1);
System.out.println(orderList);
for (Order order: orderList.getOrders()){
System.out.println(order.toString());
}
}

@Test
public void getOrderListByUserId() {
// 获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserOrderList orderList = mapper.getOrderListByUserId(1);
System.out.println(orderList);
for (Order order: orderList.getOrders()){
System.out.println(order.toString());
}
}

@Test
public void insertOrder() {
// 获取代理对象
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);

Order order = insertOrderInfo();
int rows = mapper.insertOrder(order);
sqlSession.commit();
System.out.println(rows);
System.out.println(order.getOrderNumber());
}

/**
* 添加用户信息
*
* @return User
*/
private Order insertOrderInfo() {
Order order = new Order();
// 订单号
String orderNumber = OrderNumberFactory.getOrderCode(1L);
order.setOrderNumber(orderNumber);
// 用户ID
order.setUserId(1);
// 预付金额
order.setPrepaymentAmount(10L);
// 实付金额
order.setActuallyPaidAmount(10L);
// 创建时间
order.setCreateTime(System.currentTimeMillis());
// 商品种类
order.setGoodsKind(1);
// 商品数量
order.setGoodsQuantity(1);
// 支付方式
order.setPaymentMethod("微信");
// 交易流水号
order.setTradeOn("12311");
// 优惠后价格
order.setPriceAfterDiscount(10L);
return order;
}

@After
public void closeSession(){
if (sqlSession != null){
sqlSession.close();
}
}

}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%