Mybatis的关联映射

本文介绍MyBatis处理一对一、一对多及多对多关联关系的方法,包括嵌套查询和嵌套结果两种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习目标

  • 了解数据表之间以及对象之间的三种关联关系
  • 熟悉关联关系中的嵌套查询和嵌套结果
  • 掌握一对一、一对多和多对多关联映射的使用

文章目录

1. 关联关系概述

2. 一对一

3.一对多 

 4. 多对多


1. 关联关系概述

  • 一对一的关系:就是在本类中定义对方类型的对象
  • 一对多的关系:就是一个A类类型对应多个B类类型的情况
  • 多对多的关系:在A类中定义B类类型的集合,在B类中定义A类类型的集合

2. 一对一

Mybatis通过<resultMap>中的子元素<association>来处理一对一关联关系.

<association>元素中,通常可以配置一下属性:

  • property:指定映射到的实体类对象属性,与表字段意义对应。

  • column:指定表中对应的字段。

  • javaType:指定映射到实体对象属性的类型。

  • select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询。

  • fetchType:指定在关联查询时是否启用延迟加载。fetchType属性有lazyeager两个属性值,默认值为lazy(即默认关联延迟加载)。

<association>元素只需要参考如下两种实例配置:

	<!-- 方式一:嵌套查询 -->
<association property="card" column="card_id"
			javaType="IdCard"
			select="com.mybatis.mapper.IdCardMapper.findCodeById" />

<!-- 方式二:嵌套结果 -->
<association property="card" javaType="com.mybatis.po.IdCard">
			<id property="id" column="card_id" />
			<result property="code" column="code" />
		</association>

Mybatis在映射文件中加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果。嵌套查询是指通过执行另外一条SQL映射语句来返回预期的复杂类型;嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。我们可以使用上述任何一种方式实现对关联关系的加载。

 查询个人及其关联的身份证信息是先通过查询个人表中的主 主键来获个人信息, 然后通过表中的外键,来获取证件表中的身份证号信息。其具体实现步骤如下:

(1)在mybatis数据库中分别创建名为tb_idcard和tb_person的数据表,同时预先插入两条数据。

USE mybatis;
#创建一个名称为tb_idcard的表
CREATE TABLE tb_idcard(
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR(18)
);

#插入两条数据
INSERT INTO tb_ idcard (CODE) VALUES ('152221198711020624') ;
INSERT INTO tb_ idcard (CODE) VALUES ('152201199008150317') ;

#创建一个名称为tb_ person的表
CREATE TABLE tb_ person (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32),
age INT,
sex VARCHAR(8),
card id INT UNIQUE,
FOREIGN KEY (card_ id) REFERENCES tb_idcard(id)
);

#插入两条数据
INSERT INTO tb_ person (name,age,sex,card id) VALUSE('Rose',27,'tom',27,'男',2);
INSERT INTO tb_person (name,age,sex, card _id) VALUES('tom',29, '女',1); 

(2) 在Eclipse中创建工程,然后引入相关JAR包、log4j日志文件、MybatisUtils工具类以及mybatis-config.xml核心配置文件。

(3)在项目的com.mybatis.po包下创建持久化类idCard和Person。

package com.mybatis.po;

public class IdCard {
	private Integer id;
	private String code;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

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

}
package com.mybatis.po;

public class Person {
	private Integer id;
	private String name;
	private Integer age;
	private String sex;
	private IdCard card;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public IdCard getCard() {
		return card;
	}

	public void setCard(IdCard card) {
		this.card = card;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", card=" + card + "]";
	}

}

 (4)在com.mybatis.mapper包中,创建证件映射文件idCardMapper.xml和个人映射文件PersonMapper.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.mybatis.mapper.IdCardMapper">
	<!-- 根据id查询证件信息 -->
	<select id="findCodeById" parameterType="Integer"
		resultType="IdCard">
		select * from tb_idcard where id=#{id}
	</select>
</mapper>	

<?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.mybatis.mapper.PersonMapper">
	<!-- 嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
	<select id="findPersonById" parameterType="Integer"
		resultMap="IdCardWithPersonResult">
		select * from tb_person where id=#{id}
	</select>

	<resultMap type="Person" id="IdCardWithPersonResult">
		<id property="id" column="id" />
		<result property="name" column="name" />
		<result property="age" column="age" />
		<result property="sex" column="sex" />
		
		<!-- 一对一:association使用select属性引入另外一条SQL语句 -->
		<association property="card" column="card_id"
			javaType="IdCard"
			select="com.mybatis.mapper.IdCardMapper.findCodeById" />
	</resultMap>


	<!-- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 -->
	<select id="findPersonById2" parameterType="Integer"
		resultMap="IdCardWithPersonResult2">
		select p.*,idcard.code
		from tb_person p,tb_idcard idcard
		where p.card_id=idcard.id
		and p.id=#{id}
	</select>
	<resultMap type="Person" id="IdCardWithPersonResult2">
		<id property="id" column="id" />
		<result property="name" column="name" />
		<result property="age" column="age" />
		<result property="sex" column="sex" />
		<association property="card" javaType="IdCard">
			<id property="id" column="card_id" />
			<result property="code" column="code" />
		</association>
	</resultMap>

</mapper>	

 (5)在核心配置文件mybatis-config.xml中,引入Mapper映射文件并定义别名。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 引入数据库连接配置文件 -->
	<properties resource="db.properties" />
	<!-- 使用扫描包的形式定义别名 -->
	<typeAliases>
		<package name="com.mybatis.po" />
	</typeAliases>
	<!-- 环境配置 -->
	<environments default="mysql">
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/mybatis/mapper/IdCardMapper.xml" />
		<mapper resource="com/mybatis/mapper/PersonMapper.xml" />
	</mappers>
</configuration>

 (6)在com.mybatis.test包中,创建测试类MybatisAssociatedTest,并在类中编写测试方法findPersonByIdTest()。

package com.mybatis.test;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mybatis.po.Person;
import com.mybatis.util.MybatisUtils;

/*
 * Mybatis关联查询映射测试类
 */
public class MybatisAssociatedTest {

	/*
	 * 嵌套查询
	 */

	@Test
	public void CustomerTest() throws Exception {
		// 1.通过工具类生成SqlSession对象
		SqlSession session = MybatisUtils.getSession();
		// 2.使用Mybatis嵌套查询的方式查询id为1的人的信息
		Person person = session.selectOne("com.mybatis.mapper." + "PersonMapper.findPersonById", 1);
		// 3.输出查询结果
		System.out.println(person);
		// 4.关闭SqlSession
		session.close();
	}

    /*
	 * 嵌套结果
	 */

	@Test
	public void CustomerTest2() {
		// 1.通过工具类生成SqlSession对象
		SqlSession session = MybatisUtils.getSession();
		// 2.使用Mybatis嵌套查询的方式查询id为1的人的信息
		Person person = session.selectOne("com.nynu.qdy.mapper." + "PersonMapper.findPersonById2", 1);
		// 3.输出查询结果
		System.out.println(person);
		// 4.关闭SqlSession
		session.close();
	}

}

(7) 使用JUnit4分别执行findByIdTest()和CustomerTest2()后,控制台的输出结果如下图所示。

3.一对多 

Mybatis通过<resultMap>中的子元素<collection>来处理一对多关联关系。<collection>子元素的属性与<association>元素相同,但还包括一个特殊属性——ofType。ofType属性与javaType属性对应,它用于指定实体对象中集合类属性所包含的元素类型。

<collection>元素的使用可以参考如下两种实例进行配置:

<!--方式一:嵌套查询-->
<collection property="ordersList" column="id"
        ofType="com.mybatis.po.Orders">
    select="com.mybatis.mapper.OrdersMapper.selectOrders" />
		</collection>
<!-- 方式二:嵌套结果 -->
<collection property="ordersList" ofType="Orders">
			<id property="id" column="orders_id" />
			<result property="number" column="number" />
		</collection>

 在了解了MyBatis处理一对多关联关系的元素和方式后,接下来以用户和订单之间的这种一 对多关联关系为例,详细讲解如何在MyBatis中处理一对多 关联关系,具体步骤如下:

(1) 在mybatis数据库中,创建两个数据表,分别为tb_ _user和tb_ _orders, 同时在表中预先插入几条数据,执行的SQL语句如下所示。

#创建一个名称为tb_ user的表
CREATE TABLE tb_user(
id int(32) PRIMARY KEY AUTO_INCREMENT,
username varchar (32),
address varchar (256)
);

#插入3 条数据
INSERT INTO tb_ user VALUES ('1', ' 詹姆斯',! 克利夫兰');
INSERT INTO tb user VALUES ('2', '科比,洛杉矾') ;
INSERT INTO tb user VALUES ('3', '保罗', '洛杉矶');

井创建一个名称为tb_orders 的表
CREATE TABLE tb_orders(
1d 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)
); 

#插入3条数据
INSERT INTO tb orders VALUES ('1', '1000011','1');
INSERT INTO tb orders VALUES ('2', '1000011','1');
INSERT INTO tb orders VALUES ('3', '1000011','2');

 (2) 在com.mybatis.po包中,创建持久化类Orders和User,并在两个类中定义相关属性和方法。

package com.mybatis.po;

import java.util.List;

public class Orders {
	private Integer id;
	private String number;
	private List<Product> productList;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public List<Product> getProductList() {
		return productList;
	}

	public void setProductList(List<Product> productList) {
		this.productList = productList;
	}

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

}
package com.mybatis.po;

import java.util.List;

public class User {
	private Integer id;
	private String username;
	private String address;
	private List<Orders> ordersList;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public List<Orders> getOrdersList() {
		return ordersList;
	}

	public void setOrdersList(List<Orders> ordersList) {
		this.ordersList = ordersList;
	}

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

}

(3) 在com.mybatis.mapper包中,创建用户实体类映射文件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">
<!-- namespace表示命名空间 -->
<mapper namespace="com.mybatis.mapper.UserMapper">
	<!-- 一对多:查看某一用户及其关联的订单信息 注意:当关联查询出的列名相同,则需要使用别名区分 -->
	<select id="findUserWithOrders" parameterType="Integer"
		resultMap="UserWithOrdersResult">
		select u.*,o.id as orders_id,o.number
		from tb_user u,tb_orders o
		where u.id=o.user_id
		and u.id=#{id}
	</select>
	<resultMap type="User" id="UserWithOrdersResult">
		<id property="id" column="id" />
		<result property="username" column="username" />
		<result property="address" column="address" />
		
		<!-- 一对多关联映射:collection ofType表示属性集合中元素的类型,List<Orders>属性即Order类 -->
		<collection property="ordersList" ofType="Orders">
			<id property="id" column="orders_id" />
			<result property="number" column="number" />
		</collection>
	</resultMap>
</mapper>	

(4) 在核心配置文件mybatis-config.xml中,引入Mapper映射文件。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 引入数据库连接配置文件 -->
	<properties resource="db.properties" />
	<!-- 使用扫描包的形式定义别名 -->
	<typeAliases>
		<package name="com.mybatis.po" />
	</typeAliases>
	<!-- 环境配置 -->
	<environments default="mysql">
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/mybatis/mapper/IdCardMapper.xml" />
		<mapper resource="com/mybatis/mapper/PersonMapper.xml" />
        <mapper resource="com/mybatis/mapper/UserMapper.xml" />
	</mappers>
</configuration>

(5) 在测试类MybatisAssociatedTest中,编写测试方法findUserTest()方法。

package com.mybatis.test;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mybatis.po.User;
import com.mybatis.util.MybatisUtils;

/*
 * Mybatis关联查询映射测试类
 */
public class MybatisAssociatedTest {

	/*
	 * 一对多
	 */

	@Test
	public void findUserTest() {
		// 1.通过工具类生成SqlSession对象
		SqlSession session = MybatisUtils.getSession();
		// 2.查询id为1的用户信息
		User user = session.selectOne("com.mybatis.mapper." + "UserMapper.findUserWithOrders", 1);
		// 3.输出查询结果信息
		System.out.println(user);
		// 4.关闭SqlSession
		session.close();
	}
	
}

(6)  使用JUnit执行findUserTest()方法后,控制台输出结果如下图所示。

 4. 多对多

了解了数据库中订单表与商品表之间的多对多关联关系后,下面我们就通过具体的案例来讲解如何使用MyBatis来处理这种多对多的关系,具体实现步骤如下:

(1) 创建数据表。在mybatis数据库中新建名称为tb_product和tb_ordersitem的两个数据表,同时在表中预先插入几条数据。其执行的SQL语句如下所示。

#创建一个名称为tb_product的表

CREATE TABLE tb_product(
id INT(32) PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32),
price DOUBLE
);

#插入3条数据
INSERT INTO tb_product VALUES ('1', 'Java 基础入门','44.51') ;
INSERT INTO tb_product VALUES ('2', 'Java web 程序开发入门','38.5') ;
INSERT INTO tb product VALUES ('3', 'SSM框架整合实战','50') ; 

#创建一个名称为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)
);

#插入3条数据
INSERT INTO tb_ordersitem VALUES('1','1','1');
INSERT INTO tb_ordersitem VALUES('2','1','3');
INSERT INTO tb ordersitem VALUES('3','3','3');

 (2) 在com.mybatis.po包中,创建持久化类Product,并在类中定义相关属性和方法。

package com.mybatis.po;

import java.util.List;

public class Product {
	private Integer id; // 商品id
	private String name; // 商品名称
	private Double price; // 商品单价
	private List<Orders> orders; // 与订单相关的关联属性

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Double getPrice() {
		return price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	public List<Orders> getOrders() {
		return orders;
	}

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

	@Override
	public String toString() {
		return "Product [id=" + id + ", name=" + name + ", prices=" + price + ", orders=" + orders + "]";
	}

}

(3)在com.mybatis.mapper包中,创建订单实体映射文件Ordermapper.xml和商品实体映射文件Productmapper.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.nynu.qdy.mapper.OrdersMapper">
	<!-- 多对多嵌套映射查询: 通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
	<select id="findOrdersWithProduct" parameterType="Integer"
		resultMap="OrdersWithProductResult">
		select * from tb_orders where id=#{id}
	</select>
	<resultMap type="Orders" id="OrdersWithProductResult">
		<id property="id" column="id" />
		<result property="number" column="number" />
		<collection property="productList" column="id"
			ofType="Product"
			select="com.mybatis.mapper.ProductMapper.findProductById">
		</collection>
	</resultMap>
	<!-- 多对多嵌套结果查询:查询某订单及其关联的商品详情 -->
	<select id="findOrdersWithProduct2" parameterType="Integer"
		resultMap="OrdersWithProductResult2">
		select o.*,p.id as pid,p.name,p.price
		from tb_orders
		o,tb_product p,tb_ordersitem oi
		where oi.orders_id=o.id
		and
		oi.product_id=p.id
		and o.id=#{id}
	</select>
	<resultMap type="Orders" id="OrdersWithProductResult2">
		<id property="id" column="id" />
		<result property="number" column="number" />
		<!-- 多对多关联映射:collection -->
		<collection property="productList" ofType="Product">
			<id property="id" column="id" />
			<result property="name" column="name" />
			<result property="price" column="price" />
		</collection>
	</resultMap>
</mapper>

(4)将创建的映射文件中OrderMapper.xml和ProductMapper.xml的文件路径配置到核心配置文件mybatis-config.xml中。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 引入数据库连接配置文件 -->
	<properties resource="db.properties" />
	<!-- 使用扫描包的形式定义别名 -->
	<typeAliases>
		<package name="com.mybatis.po" />
	</typeAliases>
	<!-- 环境配置 -->
	<environments default="mysql">
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/mybatis/mapper/OrdersMapper.xml" />
		<mapper resource="com/mybatis/mapper/ProductMapper.xml" />
	</mappers>
</configuration>

(5)在测试类MybatisAssociatedTest中,编写多对多关联查询的测试方法findOrdersTest()。

package com.mybatis.test;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mybatis.po.Orders;
import com.mybatis.po.User;
import com.mybatis.util.MybatisUtils;

/*
 * Mybatis关联查询映射测试类
 */
public class MybatisAssociatedTest {

	/*
	 * 多对多
	 */

	@Test
	public void findOrdersTest() {
		// 1.通过工具类生成SqlSession对象
		SqlSession session = MybatisUtils.getSession();
		// 2.查询id为1的订单中的商品信息
		Orders orders = session.selectOne("com.mybatis.mapper." + "OrdersMapper.findOrdersWithProduct", 1);
		// 3.输出查询结果信息
		System.out.println(orders);
		// 4.关闭SqlSession
		session.close();
	}

	/*
	 * 多对多嵌套查询
	 */
	@Test
	public void findOrdersTest2() {
		// 1.通过工具类生成SqlSession对象
		SqlSession session = MybatisUtils.getSession();
		// 2.使用Mybatis嵌套查询的方式查询id为1的人的信息
		Orders orders = session.selectOne("com.mybatis.mapper." + "OrdersMapper.findOrdersWithProduct2", 1);
		// 3.输出查询结果
		System.out.println(orders);
		// 4.关闭SqlSession
		session.close();
	}
}

 (6) 使用JUnit4执行findOrdersTest()方法后,控制台的输出结果如下图所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平卉陌路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值