MyBatis的关联映射之 一对多 和 多对多

MyBatis的关联映射之 一对一(嵌套查询/嵌套结果)单击前往

一对多的关系
在一个用户拥有多个订单的案例当中将会使用到一对多的关系映射:在MyBatis当中的resultMap元素的子元素collection就是用于一对多关系映射的。该元素的属性基本与association的属性一致:其中ofType对应的是javaType:它是用于指定实体对象中集合类属性所包含的元素类型。
因此,需要建立一张用户表和一张订单表:其中用户id为1的用户拥有俩个订单:数据库语句如下:

CREATE TABLE tb_user(
id INT(32) PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32),
address VARCHAR(256)
)
INSERT INTO tb_user VALUES('1','李明','中国湖南');
INSERT INTO tb_user VALUES('2','张素','中国广东');
INSERT INTO tb_user VALUES('3','王递','美国洛杉矶');

CREATE TABLE tb_orders(
id INT(32) PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(32) NOT NULL,
user_id INT(32) NOT NULL,
FOREIGN KEY (user_id) REFERENCES tb_user(id)
)
INSERT INTO tb_orders VALUES('1','110','1');
INSERT INTO tb_orders VALUES('2','114','1');
INSERT INTO tb_orders VALUES('3','119','3');

SELECT * FROM tb_user
SELECT * FROM tb_orders

随后在lzq.po这个包下面创建订单持久化类和用户持久化类:将变量进行getset封装以及重写toString方法:(下面代码省略了getset封装的代码)
Orders类

package com.lzq.po;
public class Orders {
	private Integer id;
	private String number;

	@Override
	public String toString() {
		return "Orders[id=" + id + ", number =" + number + "]";
	}
}

User类:在user类当中要引入一个多的关系,使用一个list接口进行对订单编号的保存。

package com.lzq.po;
import java.util.List;
public class User {
	private Integer id;
	private String username;
	private String address;
	private List<Orders> OrdersList;

	@Override
	public String toString() {
		return "User[id=" + id + ",username=" + username 
			+ ",address=" + address + ",OrderList=" + OrdersList + "]";
	}
}

再者就是编写映射文件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 namespace="com.lzq.mapper.UserMapper">
  <select id="findUserWithOrders" parameterType="Integer" resultMap="UserWithOrdersResult">
	  SELECT a.* ,b.id as orders_id,b.number 
	  from tb_user a ,tb_orders b
	  where a.id =b.user_id  and a.id=#{id}
  </select>
<resultMap type="User" id="UserWithOrdersResult">
		<id property="id" column="id" />
		<result property="username" column="username" />
		<result property="address" column="address" />
		<collection property="OrdersList" ofType="Orders">
		<id property="id" column="orders_id"/>
		<result property="number" column="number"/>
		</collection>
	</resultMap>
</mapper>

以及在mybatis-config.xml文件当中进行配置mapper文件:

<mapper resource="com/lzq/mapper/UserMapper.xml" />

定义一个测试方法:与前面测试一对一关系基本同理:查询id为1的用户有几个订单:

@Test
	public void findUserTest() {
		SqlSession session = MybatisUtils.getSession();
		User user = session.selectOne("com.lzq.mapper"+".UserMapper.findUserWithOrders",1);
		System.out.println(user);
		session.close();
	}

效果如下图所示:在给个id为1的值,返回的OrderList的值有俩条,也就是其所对应的俩条订单,这就是一对多关系映射:
MyBatis的关联映射之 一对多 和 多对多_第1张图片
在这里通过用户确定订单是一个一对多的关系映射,反过来通过订单确定用户就是一个一对一的关系映射:如何实现呢?如下文所示:
在Orders.java这个类当中新建一个User类的对象:包括其getset方法以及在toString方法里面对其变量进行输出:

private User user;

随后新建一个OrdersMapper,xml映射文件,对其查询的方法进行给定:给定一个订单的id查询出其信息:共有五列信息
MyBatis的关联映射之 一对多 和 多对多_第2张图片



<mapper namespace="com.lzq.mapper.OrdersMapper">
  <select id="findidByname" parameterType="Integer" resultMap="OrdersResult">
	  select a.id,a.number,a.user_id,b.username,b.address
	  from tb_user b ,tb_orders a
	  where b.id = a.user_id
	  and a.id=#{id}
  select>
  <resultMap type="Orders" id="OrdersResult">
  	<id property="id" column="id">id>
  	<result property="number" column="number">result>
  	<association property="user" javaType="User">
  		<id property="id" column="user_id">id>
  		<result property="username" column="username">result>
  		<result property="address" column="address">result>
  	association>
  resultMap>
mapper>

mybatis-config.xml文件当中引入这个映射文件:

<mapper resource="com/lzq/mapper/OrdersMapper.xml" />

最后使用一对一的关系映射的方法模板进行测试:如下图所示:给定一个订单的id 1,然后查询出其对应的用户信息:
MyBatis的关联映射之 一对多 和 多对多_第3张图片
多对多的关系

在前面的基础上,获取订单和订单商品的详情的关系,在这就需要创建一个商品信息表,和一个中间表,并且插入测试的数据:

CREATE TABLE tb_product(
id INT(32) PRIMARY KEY AUTO_INCREMENT,
pname VARCHAR(32),
price DOUBLE
)
INSERT INTO tb_product VALUES ('1','java编程基础','45');
INSERT INTO tb_product VALUES ('2','C编程基础','46.8');
INSERT INTO tb_product VALUES ('3','pyhon编程基础','52.8');

#创建一个中间表,tb_ordersitem
CREATE TABLE tb_ordersitem(
id INT(32) PRIMARY KEY AUTO_INCREMENT,
orders_id INT(32),
product_id INT(32),
FOREIGN KEY (orders_id) REFERENCES tb_orders(id),
FOREIGN KEY (product_id) REFERENCES tb_product(id)
)

INSERT INTO tb_ordersitem VALUE('1','1','1');
INSERT INTO tb_ordersitem VALUE('2','1','3');
INSERT INTO tb_ordersitem VALUE('3','3','3');

一个新的表tb_product就需要对应一个新的实体化的类Product.java,对变量进行封装,以及重写toString方法。

package com.lzq.po;
import java.util.List;

public class Product {
	private Integer id;
	private String pname;
	private Double price;
	private List<Orders> orders;
	@Override
	public String toString() {
		return "Product[id=" + id + ",pname=" + pname + 
				",price=" + price + ",orders" + orders + "]";
	}
}

在Orders当中需要添加多的一面:并且对其封装,toString方法当中添加这个变量,用于输出。

private List<Product> product;

早OrdersMapper.xml文件当中添加一条用于多对多的查询的select:

<select id="findProduct" parameterType="Integer"
		resultMap="ProductMap">
		SELECT * from tb_orders where id=#{id}
	select>
	<resultMap type="Orders" id="ProductMap">
		<id property="id" column="id" />
		<result property="number" column="number">result>
		<collection property="product" column="id"
			ofType="Product" select="com.lzq.mapper.ProductMapper.findProductByid">
		collection>
	resultMap>

在一个新的ProductMapper.xml文件当中重新定义:如下所示

<select id="findProductByid" parameterType="Integer" resultType="Product">
		select * from tb_product where id in(
			select product_id from tb_ordersitem where orders_id = #{id}
		)
	select>

最后定义一个测试方法,如下代码所示:

	@Test
	public void findOrdersTest() {
		SqlSession session = MybatisUtils.getSession();
		Orders orders = session.selectOne("com.lzq.mapper"+".OrdersMapper.findProduct",1);
		System.out.println(orders);
		session.close();
	}

效果图如下所示:
MyBatis的关联映射之 一对多 和 多对多_第4张图片

你可能感兴趣的:(#,SSM,MyBatis,关系映射,一对一,一对多)