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 ...
随机推荐
- 使用Java刷评论为平台引流的经历
场景:需要在一网站中批量评论留言. 分析接口: 列表接口获取idList,返回的是json数据直接用FastJson转就可以,如果返回的是HTML片段,则需要使用Jsoup进行提取,值得一学,常用于爬 ...
- Java/JDK各版本主要特性汇总
目录 Java18(2022.3) Java17(2021.9)(LTS版本) Java16(2021.3) Java15(2020.9) Java14(2020.3) Java13(2019.9) ...
- 记一次 .NET 某工控MES程序 崩溃分析
一:背景 1.讲故事 前几天有位朋友找到我,说他的程序出现了偶发性崩溃,已经抓到了dump文件,Windows事件日志显示的崩溃点在 clr.dll 中,让我帮忙看下是怎么回事,那到底怎么回事呢? 上 ...
- 本机无法配置远程服务器上的MySQL ODBC连接驱动
1.问题描述 我想要访问远程windows服务器上的MySQL数据库,因此需要在本地ODBC驱动上配好远程服务器的MySQL.但配置好基本信息后,测试的时候出现如下问题: 2.解决方法 之所以产生这种 ...
- Jq /Js 拖动选择文件
必须先引入 Jquery 依赖 1.文件结构 2. HTML <!DOCTYPE html> <html> <head> <meta charset=&quo ...
- 《STL源码剖析》traits技法分析
在完成一个迭代器的时候,我们可能会暴露太多的细节在外面,为了将这些细节给隐藏,我们需要封装,这也是为什么每一种STL容器都提供了一种专属的迭代器. 为了解决以"迭代器所指对象的型别" ...
- Gvim基础操作-01
Gvim基础操作 进行代码或者是文本.脚本都要使用到文本编辑工具. vi是visual的缩写,其意为可视化.它是Unix系统文本编辑的标准工具.利用光标在屏幕上的移动,用户可以方便的建立.修改或者插入 ...
- Debian 软件包管理
Debian 软件包管理 Debian 软件包管理 基础软件包管理知识 sources.list 文件格式 新手建议 档案库临时小故障 软件包依赖关系 APT 进行软件包管理 基本操作 软件包管理操作 ...
- 基于 VScode 搭建 STM32 运行环境
所需软件 vscode: 是我们的代码编辑器 STM32CubeMX: 是我们配置和初始化的软件 OpenOCD: 是开源片上调试器, 他下载完是一个压缩包, 需要配置环境 arm-none-eabi ...
- sstream中的stringstream怎么用
sstream中的stringstream怎么用 1.cin cin是从缓冲区读入,会把空格.回车等不可见的字符当做是分割,跳过.并且最后读入之后,后面会有剩余的部分,比如空格.回车等. 2.getl ...