mybatis手写多对多关联映射


这里在进行多不多关联查询配置时,需要用到一对一以及一对多查询,所以在进行mybatis的多对多关联查询之前先进行一对一以及一对多关联映射的配置,如果掌握了的话可以直接跳过第一和第二步骤
前提:sqlMapConfig.xml中进行mapper的配置
通过mapper元素加载mapper配置文件,可以通过resource属性、class指定接口方式、package指定mapper接口所在包的形式都可以。

<mappers>
		<package name="com.langsin.mapper"/>
	</mappers>

以及四个数据库表:
user表
在这里插入描述
orders表
在这里插入图片描述orderdetail表
在这里插入图片描述items表
在这里插入图片描述
这四张表的关系模型图:
在这里插入图片描述

1.一对一关联查询

1.1resultType实现

1.创建一个com.langsin.mapper包,在mapper包下,创建一个UserMapper.xml文件

<!--UserMapper.xml文件-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
					"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 命名空间的作用是对SQL进行分类管理,起到隔离SQL的作用,如果使用mapper代理,namespace有特殊重要作用 -->
<mapper namespace="com.langsin.mapper.UserMapper">
	<!--创建select标签,id对应接口中的方法名,parameterType对应传入参数,
	resultType对应返回值的类型第一个字母小写因为在sqlMapConfig.xml中进行了配置
	-->
	<select id="queryUserOrder" parameterType="int" resultType="resultExtendUser">
		select u.*,o.* from user u join orders o on u.user_id =o.user_id
		where u.user_id = #{value}
	</select>
</mapper>

2.定义mapper接口OrderMapper.java,接口与mapper配置文件在同一个包下,这里的User类和ResultExtendUser都是定义在pojo包下,User类只是和数据库简单的映射。

package com.langsin.pojo;

public class ResultExtendUser extends User{
	private String orderPrice;
	private String orderDate;
	private String userphone;
	public String getUserphone() {
		return userphone;
	}
	public void setUserphone(String userphone) {
		this.userphone = userphone;
	}
	private String useraddress;
	public String getOrderPrice() {
		return orderPrice;
	}
	public void setOrderPrice(String orderPrice) {
		this.orderPrice = orderPrice;
	}
	public String getOrderDate() {
		return orderDate;
	}
	public void setOrderDate(String orderDate) {
		this.orderDate = orderDate;
	}
	public String getUseraddress() {
		return useraddress;
	}
	public void setUseraddress(String useraddress) {
		this.useraddress = useraddress;
	}
	@Override
	public String toString() {
		return "ResultExtendUser [orderPrice=" + orderPrice + ", orderDate=" + orderDate + ", userphone=" + userphone
				+ ", useraddress=" + useraddress + ", toString()=" + super.toString() + "]";
	}
}

3.通过JUnit进行测试

@Test
	public void queryUserOrder() throws Exception{
		UserMapper mapper = session.getMapper(UserMapper.class);
		Integer userId = 3;
		List<ResultExtendUser> list = mapper.queryUserOrder(userId);
		session.close();
		for (ResultExtendUser resultExtendUser : list) {
			System.out.println(resultExtendUser);
		}
	}
1.2resultMap实现

如果在进行关联查询时,几乎两个表中所有的列都被当做查询结果,那么在扩展类中再定义另外一个表中所有的列,显然不是很合适了,这种情况下最常见的方式,就是把另外一个表所对应的POJO对象组合进来,这时使用mybatis进行输出映射就只能使用resultMap元素了,这就是resultMap的高级使用。
1.通过组合创建一个扩展类,扩展User

package com.langsin.pojo;

public class ResultMapExtendUser extends User{
	private Orders orders = null;

	public Orders getOrders() {
		return orders;
	}

	public void setOrders(Orders orders) {
		this.orders = orders;
	}

	@Override
	public String toString() {
		return "ResultMapExtendUser [orders=" + orders + ", toString()=" + super.toString() + "]";
	}
	
}

2.在配置映射时,必须设定唯一标识ID,例如配置订单信息,订单的唯一标识为:user_id

<resultMap type="resultMapExtendUser" id="userAndOrderMap">
		<id column="user_id" property="userId"/>
		<result column="user_name" property="userName"/>
		<result column="role_name" property="roleName"/>
		<association property="orders" javaType="orders">
			<id column="order_id" property="orderId"/>
			<result column="order_price" property="orderPrice"/>
			<result column="order_date" property="orderDate"/>
		</association>
	</resultMap>
	<select id="queryUserAndOrder" parameterType="int" resultMap="userAndOrderMap">
		select u.*,o.* from user u join orders o on u.user_id =o.user_id
		where o.order_id=#{value}
	</select>

2.一对多关联查询

查询用户表并关联查询订单表。在没有使用框架时,针对于这种情况,一般我们都是service层进行业务处理,首先组装一个用户扩展类,在用户扩展类中定义一个List集合来存放此用户所对应的订单。即:先调用dao层查询用户表,然后再根据用户表与订单表的主外键关联字段,再调用订单的dao再查询订单,最终完成数据组装。通过mybatis框架collection集合,可以很轻松的完成此项工作。
1.UserMapper.xml文件
colloction标签中的属性property为resultUserList的属性,ofType为orderList组成这个List集合的类型。

<resultMap type="resultUserList" id="userListOrderMap">
		<id column="user_id" property="userId"/>
		<result column="user_name" property="userName"/>
		<result column="role_name" property="roleName"/>
		<collection property="orderList" ofType="orders">
			<id column="order_id" property="orderId"/>
			<result column="order_price" property="orderPrice"/>
			<result column="order_date" property="orderDate"/>
			<result column="userphone" property="userphone"/>
			<result column="useraddress" property="useraddress"/>
		</collection>
	</resultMap>
	<select id="queryUserListAndOrder" parameterType="int" resultMap="userListOrderMap">
		select u.*,o.* from user u join orders o on u.user_id =o.user_id
		where u.user_id=#{value}
	</select>

2.UserMapper.java中的配置

public ResultUserList queryUserListAndOrder(Integer userId) throws Exception;

3.JUnit测试方法

@Test
	public void queryUserListOrderResultMap() throws Exception{
	UserMapper mapper = session.getMapper(UserMapper.class);
	Integer userId = 3;
	ResultUserList queryUserListAndOrder = mapper.queryUserListAndOrder(userId);
	for (Orders or : queryUserListAndOrder.getOrderList()) {
		System.out.println(or);
	}
	session.close();
	}

3.多对多关联查询

使用mybatis实现多对多关联查询,操作内容为:查询用户及用户购买的商品的信息。
首先进行分析,查询主表为用户表user
通过订单商品数据模型图可以看出,用户表与商品表没有直接的关联关系,但可以通过中间表:订单表orders、订单明细表orderdetail、商品表item进行关联。
UserMapper.xml中的配置

<resultMap type="resultUserLists" id="userItemDetailMap">
		<id column="user_id" property="userId"/>
		<result column="user_name" property="userName"/>
		<result column="role_name" property="roleName"/>
		<collection property="orderList" ofType="resultExtendOrders">
			<id column="order_id" property="orderId"/>
			<result column="order_price" property="orderPrice"/>
			<result column="order_date" property="orderDate"/>
			<result column="userphone" property="userphone"/>
			<result column="useraddress" property="useraddress"/>
			<collection property="detailList" ofType="orderDetail">
				<id column="detail_id" property="detailId"/>
				<result column="order_num" property="orderNum"/>
				<result column="item_id" property="itemId"/>
				<result column="buy_num" property="buyNum"/>
				<result column="order_id" property="orderId"/>
				<association property="items" javaType="Items">
					<id column="item_id" property="itemId"/>
					<result column="item_name" property="itemName"/>
					<result column="price" property="price"/>
					<result column="description" property="description"/>
				</association>
			</collection>
		</collection>
	</resultMap>
	<select id="findUserItemDetail" parameterType="int" resultMap="userItemDetailMap">
		select u.*,o.*,od.*,it.* from user u join orders o on u.user_id =o.user_id join orderdetail od on od.order_id = o.order_id
		join items it on it.item_id = od.item_id
		where u.user_id=#{value}
	</select>

2.下面开始进行配置映射关系,因为是多对多的查询,所以应该如下定义类
1)将用户信息映射到User对象中
2)在User对象中定义List orderList订单列表属性,将用户的订单映射到orderList中
3)Order中添加List detailList订单明细列表属性,将订单的明细映射到detailList中
4)在OrderDetail中添加Item item商品属性,将商品明细映射到Item中
这里没有任何扩展的类的代码就不贴了,只贴带有组合之后的类代码。
扩展User类

package com.langsin.pojo;

import java.util.List;

public class ResultUserLists extends User {
	private List<ResultExtendOrders> orderList = null;
	public List<ResultExtendOrders> getOrderList() {
		return orderList;
	}
	public void setOrderList(List<ResultExtendOrders> orderList) {
		this.orderList = orderList;
	}
	@Override
	public String toString() {
		return "ResultUserList [toString()=" + super.toString() + "]";
	}
}

扩展Orders

package com.langsin.pojo;

import java.util.List;

public class ResultExtendOrders extends Orders {
	private List<OrderDetail> detailList = null;
	public List<OrderDetail> getDetailList() {
		return detailList;
	}
	public void setDetailList(List<OrderDetail> detailList) {
		this.detailList = detailList;
	}	
}

OrderDetail组合items

package com.langsin.pojo;

public class OrderDetail {
	private Items items = null;
	public Items getItems() {
		return items;
	}
	public void setItems(Items items) {
		this.items = items;
	}
	private Integer detailId = null;
	private String orderNum =null;
	private String itemId = null;
	private Integer buyNum = null;
	private Integer orderId = null;
	public Integer getDetilId() {
		return detailId;
	}
	public void setDetilId(Integer detailId) {
		this.detailId = detailId;
	}
	public String getOrderNum() {
		return orderNum;
	}
	public void setOrderNum(String orderNum) {
		this.orderNum = orderNum;
	}
	public String getItemId() {
		return itemId;
	}
	public void setItemId(String itemId) {
		this.itemId = itemId;
	}
	public Integer getBuyNum() {
		return buyNum;
	}
	public void setBuyNum(Integer buyNum) {
		this.buyNum = buyNum;
	}
	public Integer getOrderId() {
		return orderId;
	}
	public void setOrderId(Integer orderId) {
		this.orderId = orderId;
	}
	@Override
	public String toString() {
		return "OrderDetail [items=" + items + ", detailId=" + detailId + ", orderNum=" + orderNum + ", itemId=" + itemId
				+ ", buyNum=" + buyNum + ", orderId=" + orderId + "]";
	}
}

JUnit测试

	@Test
	public void queryAllUserListOrderResultMap() throws Exception{
	UserMapper mapper = session.getMapper(UserMapper.class);
	Integer userId = 3;
	List<ResultUserLists> findUserItemDetail = mapper.findUserItemDetail(userId);
	for (ResultUserLists resultUserList : findUserItemDetail) {
		System.out.println(resultUserList);
	}
	session.close();
	}

4.resultType与resultMap总结

1、对于单表的查询基本上都用resultType实现即可。

2、 对于一对一的联合查询,如果作为查询结果的第二张的表字段不多,定义一个扩展类,然后使用resultType实现即可。

3、 如果一对一的联合查询,两个表的字段都大量的使用作为查询结果,那么在一个类中,组合另外一个类,使用resultMap进行映射实现。使用association将关联信息映射到一个对象中。

4、 对于一对多,多对多的联合查询,如果查询结果数据特殊使用resultMap,使用collection将关联信息映射到一个集合中去,如果只是针对明细的数据,建议定义扩展类,使用resultType映射实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值