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.mzph.cn/web/6141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于缓存注解的时间戳令牌防重复提交设计

文章目录 一&#xff0c;概述二&#xff0c;实现过程1、引入pom依赖2、定义缓存管理3、时间戳服务类4、模拟测试接口 三&#xff0c;测试过程1&#xff0c; 模拟批量获取2&#xff0c; 消费令牌 四&#xff0c;源码放送五&#xff0c;优化方向 一&#xff0c;概述 API接口由于…

uniapp 异步加载级联选择器(Cascader,data-picke)

目录 Props 事件方法 inputChange事件回调参数说明&#xff1a; completeChange事件回调参数说明&#xff1a; temList 属性Object参数说明 defaultItemList 属性Object参数说明 在template中使用 由于uniapp uni-ui的data-picke 不支持异步作者自己写了一个 插件市场下…

vue3 ——笔记 (表单输入,监听器)

表单输入 在Vue 3中&#xff0c;v-model指令的用法稍有不同于Vue 2。在Vue 3中&#xff0c;v-model指令实际上是一个语法糖&#xff0c;它会自动将value属性和input事件绑定到组件或元素上&#xff0c;以实现双向数据绑定。 在自定义组件中使用v-model时&#xff0c;需要在组…

数组的扩容与缩容

数组的扩容与缩容 文章目录 数组的扩容与缩容数组的扩容内存分析 数组的缩容内存分析内存分析 数组的扩容 数组扩容是指当原有数组的空间不足以容纳更多的元素时&#xff0c;创建一个新的、长度更大的数组&#xff0c;并将原数组中的元素复制到新数组中&#xff0c;然后更新原…

Word文件后缀

Word文件后缀 .docx文件为Microsoft Word文档后缀名&#xff0c;基于XML文件格式 .dotm为Word启用了宏的模板 .dotx为Word模板 .doc为Word97-2003文档&#xff0c;二进制文件格式 参考链接 Word、Excel 和 PowerPoint 的文件格式参考 Learn Microsoft

类和对象【四】运算符重载

文章目录 运算符重载的概念运算符重载&#xff08;函数&#xff09;返回值类型&#xff1a;任意类型函数名&#xff1a;operator已有操作符 运算符重载&#xff08;函数&#xff09;的特点和注意点3个比较特殊的运算符重载赋值运算符&#xff08;&#xff09;重载返回值类型和返…

嵌入式开发四:STM32 基础知识入门

为方便更好的学习STM32单片机&#xff0c;本篇博客主要总结STM32的入门基础知识&#xff0c;重点在于理解寄存器以及存储器映射和寄存器映射&#xff0c;深刻体会STM32是如何组织和管理庞大的寄存器&#xff0c;从而提高开发效率的&#xff0c;为后面的基于标准库的开发做好铺垫…

MySQL 8.4 版本(LTS) 发布,一睹为快

前言 Oracle 前几天发布了 MySQL 8.4 版本(LTS)&#xff0c; 该版本是创新版的第一个长期支持版本。详细规划&#xff0c;请移步 技术译文 | 一文了解 MySQL 全新版本模型 关于 MySQL 的版本发布规划 Oracle MySQL 官方开发团队推出的新版本将过渡到新的 MySQL 版本模型。MyS…

cefsharp实现资源替换如网页背景、移除替换标签、html标识、执行javascript脚本学习笔记(含源码说明)

(一)实现测试(仅供学习参考) 1.1 目标系统页面(登录页)和登录后首页面中2处(一个替换一个移除) 1.2 实现后效果(使用cefsharp自定义浏览器实现以上功能) 1.3 登录后页面替换和移除 系统名称和一个功能菜单li (二)通过分析代码实现脚本编写 2.1 分开处理,设置了…

IDEA 2022.1版本开始,可以直接运行Markdown里的命令行

参照这种格式&#xff1a; shell mvn clean install注意idea支持的版本&#xff1a;是从 2022.1版本开始的。 ps&#xff1a;之前有人写过了&#xff0c;感觉很实用但是蛮多开发者不一定会知道的功能。 参考资料&#xff1a; https://www.cnblogs.com/didispace/p/16144107.h…

pygame鼠标绘制

pygame鼠标绘制 Pygame鼠标绘制效果代码 Pygame Pygame是一个开源的Python库&#xff0c;专为电子游戏开发而设计。它建立在SDL&#xff08;Simple DirectMedia Layer&#xff09;的基础上&#xff0c;允许开发者使用Python这种高级语言来实时开发电子游戏&#xff0c;而无需被…

ES数据存储与查询基本原理

Elasticsearch&#xff08;ES&#xff09;简介 Elasticsearch&#xff08;ES&#xff09;是一个分布式、可扩展、近实时的搜索和分析引擎&#xff0c;它基于Lucene&#xff0c;设计用于云计算中&#xff0c;处理大规模文档检索和数据分析任务&#xff0c;常用于实现内部搜索引…

CMake:静态库链接其他动态库或静态库(九)

1、项目结构 对于下面这样一个项目 把calc模块做成静态或者动态库把sort模块做成静态库然后再sort模块中的*.cpp调用calc模块生成的库即可&#xff08;这样就制作了一个静态库引用动态或者静态库&#xff09;test模块用于测试sort模块中的内容 . ├── calc │ ├── ad…

Codeforces Round 943 (Div. 3) 题解 缺F和G2

A题&#xff1a; Maximize? 题目大意&#xff1a; 给你一个整数 x&#xff0c; 要求你找出任意一个 y &#xff0c;。使得最大。 思路一&#xff1a;暴力 数据范围小&#xff0c;直接暴力。 #include <bits/stdc.h> #define int long long #define endl \n using n…

MySQL —— 库的基本操作

一、数据库的增删查改 &#xff08;1&#xff09;创建 语句&#xff1a;create database db_name;&#xff08;db_name是自定义的数据库名字&#xff09; &#xff08;2&#xff09;删除 语句&#xff1a;drop database dp_name;&#xff08;dp_name是要被删除的数据库的名字…

【智能算法】冠豪猪优化算法(CPO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;M Abdel-Basset等人受到冠豪猪防御行为启发&#xff0c;提出了冠豪猪优化算法&#xff08;Crested Porcupine Optimizer, CPO&#xff09;。 2.算法原理 2.1算法思想 …

【Cpp】类和对象#构造函数 析构函数

标题&#xff1a;【Cpp】类和对象#构造函数 析构函数 水墨不写bug &#xff08;图片来源于网络&#xff09; 正文开始&#xff1a; &#xff08;一&#xff09;构造函数 构造函数是特殊的成员函数&#xff0c;需要注意的是&#xff0c;构造函数虽然名称叫构造&#xff0c;但…

区块链 | IPFS:Merkle DAG(进阶版)

&#x1f98a;原文&#xff1a;Merkle DAGs: Structuring Data for the Distributed Web &#x1f98a;写在前面&#xff1a;本文属于搬运博客&#xff0c;自己留存学习。 1 Merkle DAG 当我们在计算机上表示图时&#xff0c;必须通过提供节点和边的具体表示来编码我们的数据…

常用SQL命令

应用经常需要处理用户的数据&#xff0c;并将用户的数据保存到指定位置&#xff0c;数据库是常用的数据存储工具&#xff0c;数据库是结构化信息或数据的有序集合&#xff0c;几乎所有的关系数据库都使用 SQL 编程语言来查询、操作和定义数据&#xff0c;进行数据访问控制&…

yudao-cloud微服务系统系统模块+后台管理系统成功运行

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列文章目录 第一章 芋…