Mybatis进阶(映射关系多对一 )

文章目录

    • 1.需求分析
    • 2.应用实例(xml配置)
        • 1.数据表设计
        • 2.entity设计(不要使用toString会栈溢出)
          • 1.Pet.java
          • 2.User.java
        • 3.编写Mapper
          • 1.PetMapper.java
          • 2.UserMapper.java
        • 4.编写Mapper.xml
          • 1.UserMapper.xml
          • 2.PetMapper.xml
        • 5.测试UserMapperTest.java
        • 6.resultMap复用实现PetMapper.java的getPetById方法
          • 1.修改PetMapper.xml添加实现类
          • 2.测试
    • 3.应用实例(注解方式)
        • 1.UserMapperAnnotation.java
        • 2.PetMapperAnnotation.java
    • 4.课后练习(一对多)
        • 1.数据表设计
        • 2.entity设计(不要使用toString会栈溢出)
          • 1.Dept.java
          • 2.Emp.java
        • 3.编写Mapper
          • 1.DeptMapper.java
          • 2.EmpMapper.java
        • 4.编写Mapper.xml
          • 1.DeptMapper.xml
          • 2.EmpMapper.xml
        • 5.测试DeptMapperTest.java
    • 5.MyBatis映射关系总结
        • 1.一对一
          • 1.表设计
          • 2.entity设计
          • 3.Mapper设计
        • 2.一对多(多对一)
          • 1.表设计
          • 2.entity设计
          • 3.Mapper设计
          • 4.最简化的理解

1.需求分析

image-20240306141119151

2.应用实例(xml配置)

1.数据表设计
CREATE TABLE mybatis_user(id INT PRIMARY KEY auto_increment,name VARCHAR(32) NOT NULL DEFAULT ''
);CREATE TABLE mybatis_pet(id INT PRIMARY KEY auto_increment,nickname VARCHAR(32) NOT NULL DEFAULT '',user_id INT
);INSERT INTO mybatis_user VALUES(NULL, '宋江'), (NULL, '张飞');INSERT INTO mybatis_pet VALUES(NULL, '黑背', 1), (NULL, '小哈', 1);INSERT INTO mybatis_pet VALUES(NULL, '波斯猫', 2), (NULL, '贵妃猫', 2);SELECT * FROM mybatis_user;SELECT * FROM mybatis_pet;
2.entity设计(不要使用toString会栈溢出)
1.Pet.java
package com.sun.entity;/*** @author 孙显圣* @version 1.0*/
public class Pet {private Integer id;private String nickname;private User user; //一个宠物对应一个主人public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}
2.User.java
package com.sun.entity;import java.util.List;/*** @author 孙显圣* @version 1.0*/
public class User {private Integer id;private String name;private List<Pet> pets; //一个主人对应多个宠物,使用集合表示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 List<Pet> getPets() {return pets;}public void setPets(List<Pet> pets) {this.pets = pets;}}
3.编写Mapper
1.PetMapper.java
package com.sun.mapper;import com.sun.entity.Pet;import java.util.List;/*** @author 孙显圣* @version 1.0*/
public interface PetMapper {//根据用户id获取所有宠物public List<Pet> getPetByUserId(Integer userId);//根据pet的id获取对象public Pet getPetById(Integer id);
}
2.UserMapper.java
package com.sun.mapper;import com.sun.entity.User;/*** @author 孙显圣* @version 1.0*/
public interface UserMapper {//根据id获取当前用户public User getUserById(Integer id);
}
4.编写Mapper.xml
1.UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sun.mapper.UserMapper"><resultMap id="getUserByIdresultMap" type="User"><id property="id" column="id"/><result property="name" column="name"/><!--如果是一个集合类型的属性需要使用collection标签,并需要指定ofType属性来决定返回集合中存储的类型--><collection property="pets" column="id" select="com.sun.mapper.PetMapper.getPetByUserId" ofType="Pet"/></resultMap><!--public User getUserById(Integer id);--><select id="getUserById" parameterType="Integer" resultMap="getUserByIdresultMap">SELECT * FROM mybatis_user WHERE id = #{id}</select>
</mapper>
2.PetMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sun.mapper.PetMapper"><!--public List<Pet> getPetByUserId(Integer userId);--><resultMap id="getPetByUserId_resultMap" type="Pet"><id property="id" column="id"/><result property="nickname" column="nickname"/><association property="user" column="user_id" select="com.sun.mapper.UserMapper.getUserById"/></resultMap><select id="getPetByUserId" parameterType="Integer" resultMap="getPetByUserId_resultMap">SELECT * FROM mybatis_pet WHERE user_id = #{userId}</select>
</mapper>
5.测试UserMapperTest.java
import com.sun.entity.Pet;
import com.sun.entity.User;
import com.sun.mapper.PetMapper;
import com.sun.mapper.UserMapper;
import com.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;import java.util.List;/*** @author 孙显圣* @version 1.0*/
public class UserMapperTest {private SqlSession sqlSession; //相当于连接private UserMapper userMapper;//编写方法完成初始化@Before //标注了Before之后表示了在执行目标测试方法前会执行该方法public void init() {//获取到sqlSessionsqlSession = MyBatisUtils.getSqlSession();//获取到MonsterMapper对象userMapper = sqlSession.getMapper(UserMapper.class);System.out.println(userMapper.getClass());}@Testpublic void getUserById() {User user = userMapper.getUserById(1);System.out.println(user.getName() + "-" + user.getId());List<Pet> pets = user.getPets();for (Pet pet : pets) {System.out.println(pet.getId() + "-" + pet.getNickname() + "-" + pet.getUser());}if (sqlSession != null) {sqlSession.close();}}
}
6.resultMap复用实现PetMapper.java的getPetById方法
1.修改PetMapper.xml添加实现类
    <!--public Pet getPetById(Integer id);--><select id="getPetById" parameterType="Integer" resultMap="getPetByUserId_resultMap">SELECT * FROM mybatis_pet WHERE id = #{id}</select>
2.测试
    @Testpublic void getPetById() {Pet petById = petMapper.getPetById(1);System.out.println(petById.getId() + " " + petById.getNickname() + " " + petById.getUser());}

image-20240306171019487

3.应用实例(注解方式)

1.UserMapperAnnotation.java
package com.sun.mapper;import com.sun.entity.User;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;/*** @author 孙显圣* @version 1.0*/
public interface UserMapperAnnotation {//根据id获取当前用户@Results({@Result(id = true, property = "id", column = "id"),@Result(property = "name", column = "name"),//这里根据查询到的id调用pet的方法返回一个Pet对象的列表,并且是多条记录使用many@Result(property = "pets", column = "id", many = @Many(select = "com.sun.mapper.PetMapperAnnotation.getPetByUserId"))})@Select("SELECT * FROM mybatis_user WHERE id = #{id}")public User getUserById(Integer id);
}
2.PetMapperAnnotation.java
package com.sun.mapper;import com.sun.entity.Pet;
import org.apache.ibatis.annotations.*;import java.util.List;/*** @author 孙显圣* @version 1.0*/
public interface PetMapperAnnotation {@Results(id = "getPetByUserIdResultMap",value = {//这里的id表示这个resultMap的id,可以被复用@Result(id = true, property = "id", column = "id"),@Result(property = "nickname", column = "nickname"),//根据user_id来返回一个User对象,返回一个对象使用one@Result(property = "user", column = "user_id", one = @One(select = "com.sun.mapper.UserMapperAnnotation.getUserById"))})@Select("SELECT * FROM mybatis_pet WHERE user_id = #{userId}")public List<Pet> getPetByUserId(Integer userId);//根据pet的id获取对象//这里直接使用resultMap注解来复用上面的getPetByUserIdResultMap@ResultMap("getPetByUserIdResultMap")@Select("SELECT * FROM mybatis_pet WHERE id = #{id}")public Pet getPetById(Integer id);
}

4.课后练习(一对多)

image-20240306185715900

1.数据表设计
CREATE TABLE dept(
id INT PRIMARY KEY auto_increment,
name VARCHAR(32) NOT NULL DEFAULT ''
)-- 多的一方设置外键
CREATE TABLE emp(
id INT PRIMARY KEY auto_increment,
name VARCHAR(32) NOT NULL DEFAULT '',
dept_no INT NOT NULL DEFAULT 0 
)INSERT INTO dept VALUES(NULL, '财务部');
INSERT INTO dept VALUES(NULL, '外交部');INSERT into emp VALUES(NUll, '李白1', 1);
INSERT into emp VALUES(NUll, '孙悟空1', 2);
INSERT into emp VALUES(NUll, '李白2', 1);
INSERT into emp VALUES(NUll, '孙悟空2', 2);
2.entity设计(不要使用toString会栈溢出)
1.Dept.java
package com.sun.entity;import java.util.List;/*** @author 孙显圣* @version 1.0*/
public class Dept {private Integer id;private String name;//一:可级联查询多个Empprivate List<Emp> emps;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 List<Emp> getEmps() {return emps;}public void setEmps(List<Emp> emps) {this.emps = emps;}
}
2.Emp.java
package com.sun.entity;/*** @author 孙显圣* @version 1.0*/
public class Emp {private Integer id;private String name;//多:可级联查询单个Deptprivate Dept dept;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 Dept getDept() {return dept;}public void setDept(Dept dept) {this.dept = dept;}
}
3.编写Mapper
1.DeptMapper.java
package com.sun.mapper;import com.sun.entity.Dept;/*** @author 孙显圣* @version 1.0*/
public interface DeptMapper {//根据id查询部门,级联查询该部门的多个雇员public Dept findById(Integer id);}
2.EmpMapper.java
package com.sun.mapper;import com.sun.entity.Emp;import java.util.List;/*** @author 孙显圣* @version 1.0*/
public interface EmpMapper {//根据部门id查询多个雇员,并级联查询一个部门public List<Emp> findByDeptId(Integer dept_id);
}
4.编写Mapper.xml
1.DeptMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定该xml文件和哪个接口对应-->
<mapper namespace="com.sun.mapper.DeptMapper"><!--public Dept findById(Integer id);--><resultMap id="findByIdMap" type="Dept"><id property="id" column="id"/><result property="name" column="name"/><collection property="emps" column="id" ofType="Emp" select="com.sun.mapper.EmpMapper.findByDeptId"/></resultMap><select id="findById" parameterType="Integer" resultMap="findByIdMap">SELECT * FROM dept WHERE id = #{id}</select>
</mapper>
2.EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定该xml文件和哪个接口对应-->
<mapper namespace="com.sun.mapper.EmpMapper"><!--public List<Emp> findByDeptId(Integer dept_id);--><resultMap id="findByDeptIdMap" type="Emp"><id property="id" column="id"/><result property="name" column="name"/><association property="dept" column="dept_no" select="com.sun.mapper.DeptMapper.findById"/></resultMap><select id="findByDeptId" parameterType="Integer" resultMap="findByDeptIdMap">SELECT * FROM emp WHERE dept_no = #{dept_id}</select>
</mapper>
5.测试DeptMapperTest.java
import com.sun.entity.Dept;
import com.sun.mapper.DeptMapper;
import com.sun.mapper.HusbandMapper;
import com.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;/*** @author 孙显圣* @version 1.0*/
public class DeptMapperTest {private SqlSession sqlSession; //相当于连接private DeptMapper deptMapper;//编写方法完成初始化@Before //标注了Before之后表示了在执行目标测试方法前会执行该方法public void init() {//获取到sqlSessionsqlSession = MyBatisUtils.getSqlSession();//获取到MonsterMapper对象deptMapper = sqlSession.getMapper(DeptMapper.class);System.out.println(deptMapper.getClass());}@Testpublic void findById() {Dept byId = deptMapper.findById(1);System.out.println(byId.getId() +" " + byId.getName());}
}

image-20240306201131236

5.MyBatis映射关系总结

1.一对一
1.表设计
  • 有外键的是从表,被指向的是主表
  • 设置一个有外键的从表指向一个主表(一般指向主键)
2.entity设计
  • 在表中有外键的一方将外键的字段部分替换为指向的主表的entity对象
3.Mapper设计
  • 查询有外键的一方的基本信息和级联的另一方的信息
  • 注意:如果想要双向映射,不需要再加一个外键,只需要在另一个entity实体类中加上一个entity对象即可
2.一对多(多对一)
1.表设计
  • 多的一方有外键
2.entity设计
  • 一的一方
    • 基本属性
    • 一个集合,类型为多的一方
  • 多的一方
    • 基本属性
    • 一个对象,类型为一的一方
3.Mapper设计
  • 一方查询
    • 查询一方的基本信息
    • 级联查询多方的信息
  • 多方查询
    • 查询多方的基本信息
    • 级联查询单方的信息
4.最简化的理解
  • 确定一方与多方关联的列名,简述为关联列名
  • 一方查询基本信息,使用关联列名级联查询多方信息
  • 多方查询基本信息,使用关联列名查询一方信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1410218.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

初识Vue-组件化开发(应用实例)

目录 一、任务管理应用 1.介绍 2.代码 1. 任务列表组件 (TaskList.vue) 2. 添加任务组件 (AddTask.vue) 3. 应用入口组件 (App.vue) 4. 主入口文件 (main.js) 3.效果 4.总结 二、购物车 1.介绍 2.代码 1. 商品列表组件 (ProductList.vue) 2. 购物车组件 (Cart.vue…

Web APIs 学习归纳6--- BOM浏览器对象

前面几节主要针对DOM进行了学习&#xff0c;现在开始新的内容的学习---DOM浏览器对象。 DOM是更注重页面&#xff08;document&#xff09;内容的设计&#xff0c;但是BOM不仅限于页面&#xff08;document&#xff09;的设计&#xff0c;而是更加全面包括页面的刷新&#xff0…

【数据结构】:链表的带环问题

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;数据结构 &#x1f337;追光的人&#xff0c;终会万丈光芒 前言&#xff1a; 链表的带环问题在链表中是一类比较难的问题&#xff0c;它对我们的思维有一个比较高的要求&#xff0c;但是这一类…

拌合楼管理系统(十六)c#如何实现点击同时启动两个窗体,并且窗体全部关闭后才退出程序

前言&#xff1a; 好长时间没有再写博文了&#xff0c;最近项目有个需求&#xff0c;无人值守程序需要一个client端&#xff0c;主要实现两个功能&#xff0c;一个是显示安装的四个监控的画面&#xff0c;一个是显示地磅称重数量和车牌列表等一些信息。今天主要解决如何显示两个…

SQL注入漏洞--报错/union/布尔盲注/时间盲注

之前介绍了数据库的基本操作&#xff0c;今天这篇文章就来实操SQL注入。 阅读本文前可以先看一下基本操作&#xff0c;有助于更换理解本文。。。 https://blog.csdn.net/weixin_60885144/article/details/138356410?spm1001.2014.3001.5502 what SQL---结构化查询语言---S…

【目标检测】DEtection TRansformer (DETR)

一、前言 论文&#xff1a; End-to-End Object Detection with Transformers 作者&#xff1a; Facebook AI 代码&#xff1a; DEtection TRansformer (DETR) 特点&#xff1a; 无proposal&#xff08;R-CNN系列&#xff09;、无anchor&#xff08;YOLO系列&#xff09;、无NM…

从一到无穷大 #25 DataFusion:可嵌入,可扩展的模块化工业级计算引擎实现

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言架构总览与可扩展性Catalog and Data SourcesFront End逻辑计划与逻辑计划优化器…

美国零售媒体(广告业)指南:快速增长、不断扩展的业态和新兴机遇

Guide to retail media: Rapid growth, expanding formats, and emerging opportunities --- 零售媒体如何通过CTV和其他合作伙伴关系向上发展 原文作者&#xff1a;Sara Lebow | 2024年2月16日 整理编辑&#xff1a;数字化营销工兵 I 2024年5月2日 ​​​​​​​ &#…

Agent AI智能体:如何借助机器学习引领科技新潮流

文章目录 &#x1f4d1;前言一、Agent AI智能体的基本概念二、Agent AI智能体的技术进步2.1 机器学习技术2.2 自适应技术2.3 分布式计算与云计算 三、Agent AI智能体的知识积累3.1 知识图谱3.2 迁移学习 四、Agent AI智能体的挑战与机遇4.1 挑战4.2 机遇 小结 &#x1f4d1;前言…

python学习笔记B-15:序列结构之字典--字典的创建与删除

字典的创建与删除方法&#xff1a; import random #第1种创建方式 d {10:"cat", 20:"dog", 30:"monkey"} print(d) #第2种创建方式 lst1 [10,20,30] lst2["cat","dog","monkey"] d zip(lst1,lst2) print(dict…

DRF解析器源码分析

DRF解析器源码分析 1 解析器 解析请求者发来的数据&#xff08;JSON&#xff09; 使用 request.data 获取请求体中的数据。 这个 reqeust.data 的数据怎么来的呢&#xff1f;其实在drf内部是由解析器&#xff0c;根据请求者传入的数据格式 请求头来进行处理。 drf默认的解…

还在愁自己该学什么编程?适龄标准来啦(6到14岁的同学看过来哦)

文章目录 前言一、6岁以下1.推荐2.软件 二、6至10岁1.推荐2.软件&#xff08;1&#xff09;6-8:Nemo编程——Scratch图形化编程&#xff08;2&#xff09;8-10岁&#xff1a;Scratch编程——Python编程 三、10岁以后1.推荐2.软件&#xff08;1&#xff09;Python&#xff08;2&…

【二等奖水平论文】2024五一数学建模C题22页保奖论文+22页matlab和13页python完整建模代码、可视图表+分解结果等(后续会更新)

一定要点击文末的卡片&#xff0c;那是资料获取的入口&#xff01; 问题分析 2.1 问题一分析 对于问题一&#xff0c;干扰信号分析&#xff0c;分析干扰信号并识别干扰信号的时间区间。首先对数据集进行数据清洗&#xff0c;判断其异常值以及缺失值。利用matlab的find函数判…

力扣刷题第0天:只出现一次的数字

目录 第一部分:题目描述 ​第二部分:题目分析 第三部分:解决方法 3.1思路1: 双指针暴力求解 3.2 思路2&#xff1a;异或运算 第四部分:总结收获 第一部分:题目描述 第二部分:题目分析 由图片分析可得&#xff0c;该题目对算法时间复杂度有一定的要求时间复杂度为O(N)&a…

Linux的Shell脚本详解

本文目录 一、什么是 Shell 脚本文件 &#xff1f;二、编写Shell脚本1. 基本规则2. shell 变量&#xff08;1&#xff09;创建变量&#xff08;2&#xff09;引用变量&#xff08;3&#xff09;删除变量&#xff08;4&#xff09;从键盘读取变量&#xff08;5&#xff09;特殊变…

《QT实用小工具·五十二》文本或窗口炫酷有趣的滚动条——果冻条

1、概述 源码放在文章末尾 该项目实现了文本或窗口纤细的滚动条——果冻条 一个可以像弓弦一样拉出来&#xff0c;并且来回弹动的普通滚动条。 思路为此&#xff0c;但发现实际效果更像条状果冻&#xff0c;并且略有谐音&#xff0c; 故&#xff0c;称之为——“果冻条”&am…

C/C++开发环境配置

配置C/C开发环境 1.下载和配置MinGW-w64 编译器套件 下载地址&#xff1a;https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/ 下载后解压并放至你容易管理的路径下&#xff08;我是将其放在了D盘的一个software的文件中管理&#xff09; 2.…

IBM FlashSystem 5300入门级全闪存存储平台解读

IBM FlashSystem 5300作为一款面向入门级市场的全闪存存储平台&#xff0c;其发布标志着IBM在满足不同规模企业对于高性能、高性价比存储解决方案需求方面迈出了重要一步。以下是从技术角度出发&#xff0c;结合市场对比进行的客观分析&#xff1a; 技术亮点解析 高性能与高密度…

C语言 | Leetcode C语言题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; int minPathSum(int** grid, int gridSize, int* gridColSize) {int rows gridSize, columns gridColSize[0];if (rows 0 || columns 0) {return 0;}int dp[rows][columns];dp[0][0] grid[0][0];for (int i 1; i < rows; i) {dp[i…

启发式搜索算法1 - 最佳优先搜索算法

启发式搜索算法有什么优势&#xff1f; 对于复杂问题的盲目搜索&#xff0c;常用广度优先搜索和深度优先搜索这两种盲目搜索算法&#xff0c;极大极小值和Alpha-beta剪枝算法是在盲目搜索过程中&#xff0c;通过剪枝避开一些不可能的结果&#xff0c;从而提高效率。 如果搜索…