day08-MyBatis的关联映射02
MyBatis的关联映射02
3.一对多
3.1基本介绍
多对一关系也是一个基本的映射关系,多对一,也可以理解为一对多。例如:
User--Pet:一个用户可以有多只宠物
Dep--Emp:一个部门有多个员工
双向的多对一关系:通过User可以查询到对应的所有Pet,反之,通过Pet也可以级联查询到对应的User信息。
多对多的关系就是在多对一的关系上拓展
3.2案例实现
映射方式:
方式1:通过配置映射文件实现多对一
方式2:通过注解的方式实现多对一
需求说明:实现级联查询,通过user的user_id可以查询到User信息和关联的所有pet信息,反之,通过pet的pet_id也可以查询到Pet信息和user的信息
先创建user表和pet表:
-- 创建user表
CREATE TABLE `user`(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL DEFAULT ''
)CHARSET=utf8
DESC `user`;
-- 创建pet表
CREATE TABLE `pet`(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`nickname` VARCHAR(32) NOT NULL DEFAULT '',
`user_id` INT,
FOREIGN KEY (user_id) REFERENCES `user`(id)
)CHARSET=utf8

3.2.1方式一:配置方式
(1)User和Pet实体类
package com.li.entity;
/**
* @author 李
* @version 1.0
*/
public class User {
private Integer id;
private String name;
//因为一个User可以养多个宠物,mybatis使用集合体现这个关系
private List<Pet> pets;
//setter、getter方法省略
//双向映射不要使用toString方法,否则会造成栈溢出错误
}
package com.li.entity;
/**
* @author 李
* @version 1.0
*/
public class Pet {
private Integer id;
private String nickname;
//一个pet对应一个user对象
private User user;
//setter、getter方法省略
//双向映射不要使用toString方法,否则会造成栈溢出错误
}
(2)UserMapper接口和PetMapper接口
public interface UserMapper {
//通过id获取User对象
public User getUserById(Integer id);
}
public interface PetMapper {
//通过user的id获取pet对象,可能有多个因此使用集合接收
public List<Pet> getPetByUserId(Integer userId);
}
(3)UserMapper.xml,思路:
1)先通过user_id查询得到user信息
2)再根据user_id,查询对应的pet信息,并映射到user-List< Per> pets
多对多的映射思路和一对一的实现类似,不同的使用使用resultMap映射属性时使用的是collecting标签。
<mapper namespace="com.li.mapper.UserMapper">
<!--通过id获取User对象
public User getUserById(Integer id);-->
<select id="getUserById" parameterType="Integer" resultMap="resultUserMap">
SELECT * FROM `user` WHERE id = #{id};
</select>
<!--User的属性映射-->
<resultMap id="resultUserMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<!--1.因为pets属性是一个集合,因此要使用collection标签
2.column="id"的id是SELECT * FROM `user` WHERE id=#{id} 返回的字段
3.ofType="Pet"指定返回的集合存放的数据类型-->
<collection property="pets" column="id" ofType="Pet"
select="com.li.mapper.PetMapper.getPetByUserId"/>
</resultMap>
</mapper>
(4)PetMapper.xml,思路和前面大体相同
<mapper namespace="com.li.mapper.PetMapper">
<!--通过user的id获取pet对象,可能有多个因此使用集合接收
public List<Pet> getPetByUserId(Integer userId);-->
<select id="getPetByUserId" parameterType="Integer" resultMap="resultPetMap">
SELECT * FROM `pet` WHERE user_id =#{userId};
</select>
<resultMap id="resultPetMap" type="Pet">
<id property="id" column="id"/>
<result property="nickname" column="nickname"/>
<association property="user" column="user_id"
select="com.li.mapper.UserMapper.getUserById"/>
</resultMap>
</mapper>
(5)测试getUserById()方法,通过UserId查找user对象和联系的pet信息
@Test
public void getUserById() {
User user = userMapper.getUserById(2);
System.out.println("user信息=" + user.getId() + "-" + user.getName());
for (Pet pet : user.getPets()) {
System.out.println("宠物信息=" + pet.getId() + "-" + pet.getNickname());
}
if (sqlSession != null) {
sqlSession.close();
}
}
测试结果:

(6)测试getPetByUserId()方法,通过user的id获取pet对象
@Test
public void getPetByUserId() {
List<Pet> pets = petMapper.getPetByUserId(1);
for (Pet pet : pets) {
System.out.println("UserId=" + pet.getUser().getId()
+ "-PetId=" + pet.getId()
+ "-PetNickName=" + pet.getNickname());
}
if (sqlSession != null) {
sqlSession.close();
}
}
测试结果:

resultMap可以复用,如果有其他方法是返回的和resultMap一样的类型,可以在实现该方法时引用该resultMap。
比如PetMapper接口中新声明了一个方法:
//通过pet的id获取Pet对象,同时查询到pet对象关联的user对象
public Pet getPetById(Integer id);
PerMapper.xml文件:
<!--这里可以直接复用之前的resultPetMap-->
<select id="getPetById" parameterType="Integer" resultMap="resultPetMap">
SELECT * FROM `pet` where id =#{id};
</select>
3.2.2方式二:注解方式
需求说明:通过注解的方式,实现双向的级联查询。
在实际开发中推荐使用配置的方式来做
(1)User和Pet实体类不变
(2)直接在接口中,通过注解实现级联查询
UserMapperAnnotation.java
package com.li.mapper;
import com.li.entity.User;
import org.apache.ibatis.annotations.*;
/**
* @author 李
* @version 1.0
* 以注解的方式来实现多对一
*/
public interface UserMapperAnnotation {
//通过id获取User对象
@Select(value = "SELECT * FROM `user` WHERE id = #{id}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "name", column = "name"),
//这里对应返回List类型属性pets,使用注解的many属性
@Result(property = "pets", column = "id",
many = @Many(select =
"com.li.mapper.PetMapperAnnotation.getPetByUserId"))
})
public User getUserById(Integer id);
}
PetMapperAnnotation.java
package com.li.mapper;
import com.li.entity.Pet;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author 李
* @version 1.0
*/
public interface PetMapperAnnotation {
//通过user的id获取pet对象
@Select(value = "SELECT * FROM `pet` WHERE user_id =#{userId}")
//配置了id之后就可以复用PetResuleMap
@Results(id = "PetResuleMap", value = {
@Result(id = true, property = "id", column = "id"),
@Result(property = "nickname", column = "nickname"),
@Result(property = "user", column = "user_id",
one = @One(select =
"com.li.mapper.UserMapperAnnotation.getUserById"))
})
public List<Pet> getPetByUserId(Integer userId);
//通过pet的id获取pet信息
@Select(value = " SELECT * FROM `pet` where id =#{id}")
@ResultMap("PetResuleMap")//复用上面的PetResuleMap
public Pet getPetById(Integer id);
}
3.3练习
自己设计dept(部门)和emp(雇员)表,它们是一对多的关系。
- 通过查询dept,可以级联查询到所有的emp信息
- 通过查询emp,也可以级联查询到对应的dept信息
- 拓展思考:多对多关系
day08-MyBatis的关联映射02的更多相关文章
- 04—mybatis的关联映射
mybatis的关联映射一对一一对多多对多 一.一对一(一个人只能有一个身份证号) 1.创建表创建表tb_card CREATE TABLE `tb_card` ( `id` int(11) NOT ...
- mybatis 一对一关联映射实例
在实际项目开发中,经常存在一对一的关系,如一个人对应一张身份证信息,这就是一对一的关系.下面是一个简单的实例: 1.建表过程我就省略了,主要是一张Person表,一张IDCard表,其相关属性见步骤2 ...
- mybatis之关联映射
###mybatis使用之一对一关联映射 1)分析并画ER图.(特别是一对一.一对多.多对多的情况) 2)启动终端数据库,并建库建表,在表中插入值和字段,并查看结果.(后期把navicat用上) 3) ...
- Mybatis的关联映射案例
主要是对之前学习的关联映射做一个案例,自己动手实践一下,可以理解的更好一点. 开发环境 开发工具:idea Java环境: jdk1.8.0_121 数据库:SQLServer 项目结构,里面包含了三 ...
- Mybatis的关联映射
实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系.针对多表之间的操作,MyBatis提供了关联映射, 通过关联映射就可以很好的处理对象与对象之间的关联关 ...
- MyBatis的关联映射和动态SQL
CREATE TABLE tb_card ( id INT PRIMARY KEY AUTO_INCREMENT, CODE ) ); '); CREATE TABLE tb_person ( id ...
- 【Hibernate框架】关联映射(一对一关联映射)
一.整理思路: 之前,小编总结过Mybatis的关联映射,接下来,再来总结一下hibernate的相关的关联映射,直接上图: 这张图,就是小编整理总结整个Hibernate的关联映射的一个大致思路. ...
- Mybatis(四)关联映射
一. Mybatis关联映射 1 讲数据库中关联关系,主键表与外键表 一对多,多对一,主键表表示一 与外键表表示多 学生与学校的关系,工人与工厂,人员与部门的关系,.... 多 一 ...
- SSM框架开发web项目系列(三) MyBatis之resultMap及关联映射
前言 在上篇MyBatis基础篇中我们独立使用MyBatis构建了一个简单的数据库访问程序,可以实现单表的基本增删改查等操作,通过该实例我们可以初步了解MyBatis操作数据库需要的一些组成部分(配置 ...
- MyBatis学习(七)MyBatis关联映射之多对多映射
对于数据库中的多对多关系建议使用一个中间表来维护关系. 1.创建四张表,分别为用户表,商品表,订单表,中间表. DROP TABLE IF EXISTS `t_user`; CREATE TABLE ...
随机推荐
- 2022年Kubernetes CKA 认证真题解析完整版
第一题 RBAC授权问题权重: 4% 设置配置环境:[student@node-1] $ kubectl config use-context k8s Context为部署管道创建一个新的Cluste ...
- 微服务组件-----Spring Cloud Alibaba 注册中心Nacos的CP架构Raft协议分析
前言 本篇幅是继 注册中心Nacos源码分析 的下半部分. 意义 [1]虽说大部分我们采用注册中心的时候考虑的都是AP架构,为什么呢?因为性能相对于CP架构来说更高,需要等待的时间更少[相对于CP架 ...
- Clickhouse表引擎探究-ReplacingMergeTree
作者:耿宏宇 1 表引擎简述 1.1 官方描述 MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中.数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合 ...
- HMS Core 3D流体仿真技术,打造移动端PC级流体动效
移动设备硬件的高速发展,让游戏行业发生翻天覆地的变化,许多酷炫的游戏效果不再局限于电脑端,玩家在移动端就能享受到场景更逼真.画质更清晰.体验更流畅的游戏服务.但由于移动设备算力不足,为了实现真实感的水 ...
- Django(2) - Django模板
1.Django模板介绍 基础概念 模板是具有一定的格式或骨架,可以动态的生成HTML 模板引擎决定以何种方式组织代码 一个项目可以有一个或者是多个模板引擎,Django里面主要两个模板引擎:DTL. ...
- 3_多维数组转一维数组 reduce()
一,二维数组转一维数组 1 //1. 二维数组转一维数组 2 let arr = [[0,1],[2,3],[4,5]] 3 let newArr = arr.reduce((pre,cur) =&g ...
- MongoDB - 分片简介
简介 什么是分片 高数据量和高吞吐量的数据库应用会对单机的性能造成较大压力,大的查询会将单机的 CPU 耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存压力转移到磁盘 IO 上. 为了解决这 ...
- Debian 软件包管理
Debian 软件包管理 Debian 软件包管理 基础软件包管理知识 sources.list 文件格式 新手建议 档案库临时小故障 软件包依赖关系 APT 进行软件包管理 基本操作 软件包管理操作 ...
- 数学 in OI-数论-1
数论 \(1\) \(1.\) 质数 定义就不说了吧. 性质 \(\&\) 定理 质数 \(p\) 有且仅有两个质因子 \(1\) 和 \(p\) . 质数有无穷个. \([1,\, n]\) ...
- angular--路由导航三种方法