六、Mybatis级联查询之集合对象映射关系的处理

本文详细介绍了在MyBatis中如何通过级联查询实现用户表和订单表的一对多关联查询,包括使用collection标签配置映射关系、创建UserMapper.xml文件以及测试查询结果的具体步骤。

上一篇文章介绍了查询订单记录级联查询用户记录的操作,今天介绍下查询用户记录级联查询多个所属订单的操作方式。

用户表和订单表的关系是一对多,这种从一方查询关联查询多方的操作还是比较常见的。

对应的sql语句查询就是这样:

select u.*,o.id oid,user_id,number,createtime from user u,orders o where u.id = o.user_id;

执行结果:
在这里插入图片描述

用mybatis来实现的话,操作步骤如下:

1.在一方的javabean中添加多方
用过hibernate的就很熟悉了,直接在一方中添加一个List集合,集合的泛型参数就是多方的类型,同样在mybatis中也是一样。

由于我用的还是上一个工程的demo,为了和之前的操作区分,我这里单独创建一个用户类,就叫User2类,代码如下:

public class User2 {
	private int id;
	private String username;// 用户姓名
	private int sex;// 性别
	private Date birthday;// 生日
	private String address;// 地址

	private List<Orders> orders; //一对多中的多方
	
	//getter and setter...
}

订单表还是用Orders类,代码如下:

public class Orders {
    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private String note;
    
    //getter and setter...
}

2.配合映射关系

创建UserMapper.xml文件,同样需要用到resultMap标签,和一对一的使用不同的就是resultMap标签体内不再使用association 标签而是使用collection标签来配置另一方的映射关系。

collection标签的属性有2个:

  • property:指用于表示多方的集合在一方对象中的属性名称
  • ofType:指该集合的泛型参数的类型(全路径名称)

然后collection标签体内同样需要用到id标签和result标签来设置查询语句的字段和javabean属性的对应关系。

因此,查询用户表级联查询订单表的resultMap可以这样定义:

<!-- 处理user表和order表的sql查询语句字段在javabean中的映射  -->
<resultMap id="userAndOrdersResultMap" type="blog.youkuaiyun.com.mchenys.poj.User2" >
	
	<!-- 用户表sql语句字段的映射(一方) -->
	<id column="id" property="id"/>
	<result column="username" property="username"/>
	<result column="sex" property="sex"/>
	<result column="birthday" property="birthday"/>
	<result column="address" property="address"/>
	
	<!-- 订单表sql语句字段的映射(多方)-->
	<collection property="orders" ofType="blog.youkuaiyun.com.mchenys.poj.Orders">
		<!--这里是oid,是因为订单查询的sql语句中对订单表的id起了别名叫oid  -->
		<id column="oid" property="id"/>
		<result column="user_id" property="userId"/>
		<result column="number" property="number"/>
		<result column="createtime" property="createtime"/>
		<result column="note" property="note"/>
		
	</collection>
</resultMap>

使用方式还是一样,在select标签的resultMap属性进行引用,如下所示:

<!-- 一对多的映射  -->
<select id="findUserAndOrders" resultMap="userAndOrdersResultMap">
	select u.*,o.id oid,user_id,number,createtime 
	from user u,orders o 
	where u.id = o.user_id;
</select>

完整的UserMapper.xml配置文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- mapper接口代理实现规则: 
	1.映射文件中namespace要等于接口的全路径名称 
	2. 映射文件中sql语句的id要等于接口的方法名称 
	3. 映射文件中传入参数类型要等于接口方法的传入参数类型 
	4. 映射文件中返回结果集类型要等于接口方法的返回值类型,如果接口方法的返回值类型是集合,那么它表示的就是集合中的泛型参数类型 -->
<mapper namespace="blog.youkuaiyun.com.mchenys.mapper.UserMapper">

	<!-- 处理user表和order表的sql查询语句字段在javabean中的映射  -->
	<resultMap id="userAndOrdersResultMap" type="blog.youkuaiyun.com.mchenys.poj.User2" >
		
		<!-- 用户表sql语句的映射(一方) -->
		<id column="id" property="id"/>
		<result column="username" property="username"/>
		<result column="sex" property="sex"/>
		<result column="birthday" property="birthday"/>
		<result column="address" property="address"/>
		
		<!-- 订单表sql语句的映射(多方)-->
		<collection property="orders" ofType="blog.youkuaiyun.com.mchenys.poj.Orders">
			<!--这里是oid,是因为查询的语句中对订单表的id起了别名  -->
			<id column="oid" property="id"/>
			<result column="user_id" property="userId"/>
			<result column="number" property="number"/>
			<result column="createtime" property="createtime"/>
			<result column="note" property="note"/>
			
		</collection>
	</resultMap>

	<!-- 一对多的映射  -->
	<select id="findUserAndOrders" resultMap="userAndOrdersResultMap">
		select u.*,o.id oid,user_id,number,createtime 
		from user u,orders o 
		where u.id = o.user_id;
	</select>
	
	
</mapper>

创建UserMapper接口并添加findUserAndOrders查询方法:

package blog.csdn.net.mchenys.mapper;

import java.util.List;

import blog.csdn.net.mchenys.poj.User2;

public interface UserMapper {
	
	//查询用户级联查询多个订单
	List<User2> findUserAndOrders();
}

创建UserMapperTest测试类,代码如下:

package blog.csdn.net.mchenys.test;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import blog.csdn.net.mchenys.mapper.UserMapper;
import blog.csdn.net.mchenys.poj.Orders;
import blog.csdn.net.mchenys.poj.User2;

public class UserMapperTest {
	private SqlSessionFactory factory;

	@Before
	public void setUp() throws Exception {
		InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
		factory = new SqlSessionFactoryBuilder().build(config);
	}

	@Test
	public void findUserAndOrders() {
		SqlSession session = factory.openSession();
		UserMapper mapper = session.getMapper(UserMapper.class);
		List<User2> list = mapper.findUserAndOrders();
		for (User2 user : list) {
			System.out.print("用户id=" + user.getId() + ", 用户名=" + user.getUsername()+", 订单信息[");
			
			for(Orders order : user.getOrders()) {
				System.out.print("{订单id="+order.getId()+", 订单数量="+order.getNumber()+"},");
			}
			System.out.println("]");
		}
	}

}

测试结果如下:
在这里插入图片描述
上图可见,用户id=1的对应有2条订单记录,用户id=10的对应有一条订单记录,和开篇的sql语句执行结果一样,搞定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值