Mybatis 多对一和一对多查询

news/2025/1/17 1:02:21/

文章目录

  • Mybatis 多对一 and 一对多查询详解
    • 数据库
    • 需求
    • Mybatis代码
    • 注意

Mybatis 多对一 and 一对多查询详解

数据库

员工表 t_emp

在这里插入图片描述

部门表 t_dept在这里插入图片描述


CREATE TABLE `t_emp` (`emp_id` int NOT NULL AUTO_INCREMENT,`emp_name` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,`age` int DEFAULT NULL,`gender` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,`dept_id` int DEFAULT NULL,PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;CREATE TABLE `t_dept` (`dept_id` int NOT NULL AUTO_INCREMENT,`dept_name` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;INSERT INTO `t_emp` (`emp_id`, `emp_name`, `age`, `gender`, `dept_id`) VALUES (1, '张三', 20, '男', 1), (2, '李四', 22, '男', 2), (3, '王五', 23, '男', 3), (4, '赵六', 24, '男', 1);INSERT INTO `t_dept` (`dept_id`, `dept_name`) VALUES (1, 'A'), (2, 'B'), (3, 'C');

需求

多对一:员工表对应部门表
查询指定id的员工以及其对应的部门

一对多:部门表对应员工表
查询指定的部门以及其包含的员工


Mybatis代码

在这里插入图片描述

DeptMapper接口文件

package com.atguigu.mybatis.mapper;import com.ruanjian.pojo.Dept;
import com.ruanjian.pojo.Emp;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface DeptMapper {// 一对多查询// 查询部门表中的员工信息// 需要在部门类中添加员工的集合  private List<Emp> emps;Dept getDeptAndEmpById(@Param("deptId") Integer deptId);// 分步查询// 1.先查出指定id的部门信息,部门信息中有对应员工的dept_idDept getDeptAndEmpByStepOne(@Param("deptId") int deptId);// 2.再根据dept_id查出相对应的员工信息List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") int deptId);}

EmpMapper接口文件

package com.atguigu.mybatis.mapper;
import com.ruanjian.pojo.Dept;
import com.ruanjian.pojo.Emp;
import org.apache.ibatis.annotations.Param;public interface EmpMapper {// 多对一查询// 查询指定id员工以及该员工所对应的部门信息Emp getEmpAndDeptById(@Param("empId") Integer empId);Emp getEmpAndDeptById_association(@Param("empId") Integer empId);// 分步查询// 先从员工表中查询出指定id的员工的数据,该数据中有对应部门id// 再根据部门id从部门表中查询出对应的部门信息// 分步查询第一步Emp getEmpAndDeptByIdOne(@Param("empId") Integer empId);// 分步查询第二步Dept getEmpAndDeptByIdTwo(@Param("deptId") Integer deptId);
}

Dept类文件 部门实体类
package com.ruanjian.pojo;/*
员工对部门 是多对一,多对一是在多的那个类(员工类)中添加一个部门对象
部门对员工 是一对多,一对多是在一的那个类中(部门类)中添加一个员工集合对一 对的就是一个对象
对多 对的就是一个集合*/import java.util.List;// 部门实体类
public class Dept {private Integer deptId;private String deptName;private List<Emp> emps;  // 添加的一个员工的集合public Dept() {}public Dept(Integer deptId, String deptName) {this.deptId = deptId;this.deptName = deptName;}public Integer getDeptId() {return deptId;}public void setDeptId(Integer deptId) {this.deptId = deptId;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName = deptName;}public List<Emp> getEmps() {return emps;}public void setEmps(List<Emp> emps) {this.emps = emps;}@Overridepublic String toString() {return "Dept{" +"deptId=" + deptId +", deptName='" + deptName + '\'' +", emps=" + emps +'}';}
}

Emp类文件
员工实体类

package com.ruanjian.pojo;/*
员工对部门 是多对一,多对一是在多的那个类(员工类)中添加一个部门对象
部门对员工 是一对多,一对多是在一的那个类中(部门类)中添加一个员工集合对一 对的就是一个对象
对多 对的就是一个集合*/// 员工实体类// 对一就是对应的一个对象
// 对多就是对应的一个集合
public class Emp {private Integer empId;private String empName;private Integer age;private String gender;private Dept dept;  // 加上一个部门的对象public Emp() {}public Emp(Integer empId, String empName, Integer age, String gender) {this.empId = empId;this.empName = empName;this.age = age;this.gender = gender;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId = empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName = empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public Dept getDept() {return dept;}public void setDept(Dept dept) {this.dept = dept;}@Overridepublic String toString() {return "Emp{" +"empId=" + empId +", empName='" + empName + '\'' +", age=" + age +", gender='" + gender + '\'' +", dept=" + dept +'}';}
}

DeptMapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.mapper.DeptMapper"><!-- 处理一对多的映射关系1. collection2. 分步查询
-->
<!--*************************** 一对多 collection ****************************************--><resultMap id="deptAndEmpById_resultMap" type="dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><!--    collection : 处理一对多的映射关系(处理集合类型的属性)--><!--        ofType表示的是集合中的类型--><collection property="emps" ofType="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result></collection></resultMap><!--    Dept getDeptAndEmpById(@Param("deptId") Integer deptId);--><select id="getDeptAndEmpById" resultMap="deptAndEmpById_resultMap">select *from t_deptleft join t_emp on t_dept.dept_id = t_emp.dept_idwhere t_dept.dept_id=#{deptId}</select><!--*************************** 一对多 collection ****************************************--><!--*************************** 一对多  分步查询  ****************************************--><resultMap id="deptAndEmpResultMapByStep" type="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><collection property="emps"select="com.atguigu.mybatis.mapper.DeptMapper.getDeptAndEmpByStepTwo"column="dept_id"></collection></resultMap><!--    Dept getDeptAndEmpByStepOne(@Param("deptId") int deptId);// 先查出指定id的部门信息,部门信息中有对应员工的dept_id --><select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">select * from t_dept where dept_id = #{deptId}</select><!--    List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") int deptId);// 再根据dept_id查出相对应的员工信息--><select id="getDeptAndEmpByStepTwo" resultType="Emp">select * from t_emp where dept_id = #{deptId}</select></mapper>

EmpMapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.mapper.EmpMapper"><!--处理多对一的映射关系有三种方法:第一种:级联方式处理第二种:association 处理多对一的映射关系(处理的是实体类类型的属性)第三种:分布查询--><!-- ************ 第一种:级联方式处理  *************** --><resultMap id="EmpAndDeptById_resultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><result column="dept_id" property="dept.deptId"></result><result column="dept_name" property="dept.deptName"></result></resultMap><!--Emp getEmpAndDeptById(@Param("empId") Integer empId);--><select id="getEmpAndDeptById" resultMap="EmpAndDeptById_resultMap">select *from t_empleft join t_dept on t_emp.dept_id = t_dept.dept_idwhere t_emp.emp_id=#{empId}</select><!-- *********************************************--><!-- *************** 第二种 association ******************************--><!--  第二种 association--><resultMap id="getEmpAndDeptById_association_resultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><!--association: 处理多对一的映射关系(处理实体类类型的属性)property: 设置需要处理映射关系的属性的属性名javaType: 设置要处理的属性的类型, 就是把<association>标签下设置映射关系的字段,封装给某个类--><association property="dept" javaType="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result></association></resultMap><!--    Emp getEmpAndDeptById_association(@Param("empId") Integer empId);--><select id="getEmpAndDeptById_association" resultMap="getEmpAndDeptById_association_resultMap">select *from t_empleft join t_dept on t_emp.dept_id = t_dept.dept_idwhere t_emp.emp_id=#{empId}</select><!-- *********************************************--><!-- ****************** 第三种:分布查询 ***************************--><resultMap id="getEmpAndDeptByIdOne_resultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><!--property: 设置需要处理映射关系的属性的属性名select: 填写分步查询的sql的唯一标识,就是设置下一步要执行的sql语句column: 将上一个sql查询出的某个字段作为分步查询的下一个sql语句sql条件,相当于函数的参数,传给下一个sql语句fetchType: 在开启了延时加载的环境中,通过该属性设置当前的分步查询是否使用延迟加载有两个值:eager(立即加载) lazy(延迟加载)--><association property="dept"fetchType="eager"select="com.atguigu.mybatis.mapper.EmpMapper.getEmpAndDeptByIdTwo"column="dept_id"></association></resultMap><!--    Emp getEmpAndDeptByIdOne(@Param("empId") Integer empId);--><select id="getEmpAndDeptByIdOne" resultMap="getEmpAndDeptByIdOne_resultMap">select * from t_emp where emp_id = #{empId}</select><!--    Dept getEmpAndDeptByIdTwo(@Param("deptId") Integer deptId);--><select id="getEmpAndDeptByIdTwo" resultType="Dept">select * from t_dept where dept_id = #{deptId}</select><!-- *********************************************--></mapper>

ResultMapTest

import com.atguigu.mybatis.mapper.DeptMapper;
import com.atguigu.mybatis.mapper.EmpMapper;
import com.ruanjian.pojo.Dept;
import com.ruanjian.pojo.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;public class ResultMapTest {private SqlSession session;/*处理多对一的映射关系有三种方法:第一种:级联方式处理第二种:association 处理多对一的映射关系(处理的是实体类类型的属性)第三种:分步查询*/// *********************** 多对一  ****************************************@Test// 第三种:分步查询public void textGetEmpAndDeptByIdOne() {EmpMapper mapper = session.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByIdOne(1);System.out.println(emp);}@Test// 第二种:associationpublic void textGetEmpAndDeptById_association() {EmpMapper mapper = session.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptById_association(2);System.out.println(emp);}@Test// 第一种:级联方式处理public void textGetEmpAndDeptById() {EmpMapper mapper = session.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptById(2);System.out.println(emp);}// *********************** 一对多  ****************************************@Test// 分步查询public void textGetDeptAndEmpByStep() {DeptMapper mapper = session.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmpByStepOne(2);System.out.println(dept);}@Test// 一对多查询public void textGetDeptAndEmpById() {DeptMapper mapper = session.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmpById(1);System.out.println(dept);}// ***************************************************************// junit会在每一个@Test方法前执行@Before方法@Beforepublic void init() throws IOException {session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession();}// junit会在每一个@Test方法后执行@After方法@Afterpublic void clear() {session.commit();session.close();}
}

db.properties

mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
mysql.username=root
mysql.password=123456

log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"><param name="Encoding" value="UTF-8"/><layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n"/></layout></appender><logger name="java.sql"><level value="debug"/></logger><logger name="org.apache.ibatis"><level value="info"/></logger><root><level value="debug"/><appender-ref ref="STDOUT"/></root>
</log4j:configuration>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--环境配置--><!--引入外部db.properties--><properties resource="db.properties"/><settings><!--        <setting name="cacheEnabled" value="true" />--><!--  开启延时加载--><setting name="lazyLoadingEnabled" value="true"/><!-- 开启时即为true时任何方法的调用都会加载相关类的全部属性false时是按需加载,true是全部加载--><setting name="aggressiveLazyLoading" value="false"/><setting name="mapUnderscoreToCamelCase" value="true"/></settings><typeAliases><package name="com.ruanjian.pojo"/></typeAliases><!--配置mybatis的连接环境(可以配置多个环境)--><environments default="development"><!--开发环境--><environment id="development"><!--使用JDBC事务管理--><transactionManager type="JDBC"/><!--数据库连接相关配置,db.properties文件中的内容--><!--使用连接池技术--><dataSource type="POOLED"><!--数据库驱动--><property name="driver" value="${mysql.driver}"/><!--连接字符串--><property name="url" value="${mysql.url}"/><!--数据库用户名--><property name="username" value="${mysql.username}"/><!--数据库密码--><property name="password" value="${mysql.password}"/></dataSource></environment></environments><!--mapping文件路径配置--><mappers><!--        <mapper resource="mapper/DeptMapper.xml"/>--><package name="com.atguigu.mybatis.mapper"/></mappers>
</configuration>

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>MyBaits_2</artifactId><version>1.0-SNAPSHOT</version><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target></configuration></plugin></plugins></build><properties><maven.compiler.sourece>11</maven.compiler.sourece><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version><scope>runtime</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>text</scope></dependency><!-- log4j日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>
</project>

注意

新建包时用点
例如:com.atguigu.mybatis.mapper

resources目录下建立多层目录的时候时是用分割线
例如:com/atguigu/mybatis/mapper


mybatis-config.xml文件中

<package name="com.atguigu.mybatis.mapper"/>

<package>的使用条件:
接口文件要和xml文件同名,并且在同一个目录下

使用注解写的接口,只能有class的方式注册,例:

<mapper class="com.atguigu.mybatis.mapper.DeptMapper"></mapper>

http://www.ppmy.cn/news/1187068.html

相关文章

metaRTC集成flutter ui demo编译指南

概要 Flutter是由Google开发的开源UI工具包&#xff0c;用于构建跨平台应用程序&#xff0c;支持linux/windows/mac/android/ios等操作系统。 metaRTC新增flutter demo&#xff0c;支持linux/windows/mac/android/ios操作系统&#xff0c;此demo在ubuntu桌面环境下测试成功。…

Linux的基础常用指令

常用指令汇及其功能 ls 列出当前文件夹有哪些文件 ls -a显示所有文件&#xff0c;包含隐藏的文件和文件夹pwd显示当前是在哪个文件夹下mkdirmkdir名字→创建文件夹cdcd名字→进入某个指定文件夹cd .. 退回上层文件夹(cd后有空格) Tab键自动补全&#xff1a;文件或文件名太长&a…

企业金蝶KIS软件服务器中了locked勒索病毒怎么办,勒索病毒解密

最近一段时间&#xff0c;网络上的locked勒索病毒又开始了新一波的攻击&#xff0c;给企业的正常生产生活带来了严重影响。经过最近一段时间云天数据恢复中心对locked勒索病毒的解密&#xff0c;为大家整理了以下有关locked勒索病毒的相关信息。近期locked勒索病毒主要攻击金蝶…

腾讯云轻量服务器“镜像类型”以及“镜像”选择方法

腾讯云轻量应用服务器镜像类型分为应用镜像、系统镜像、Docker基础镜像、自定义镜像和共享镜像&#xff0c;腾讯云百科txybk.com来详细说下不同镜像类型说明和详细介绍&#xff1a; 轻量应用服务器镜像类型说明 腾讯云轻量应用服务器 应用镜像&#xff1a;独有的应用镜像除了包…

美妆造型教培服务预约小程序的作用是什么

美业市场规模很高&#xff0c;细分类目更是比较广&#xff0c;而美妆造型就是其中的一类&#xff0c;从业者也比较多&#xff0c;除了学校科目外&#xff0c;美妆造型教培机构也有生意。 对机构来说主要目的是拓客引流-转化及赋能&#xff0c;而想要完善路径却是不太容易&…

2023年华为云双11有什么优惠活动?详细攻略来了!

随着双十一的临近&#xff0c;华为云也开启了双11大促&#xff0c;推出了“华为云11.11”活动&#xff0c;那么&#xff0c;2023年华为云双11的优惠活动究竟有哪些呢&#xff1f;本文将为大家详细介绍。 一、华为云双11活动入口 活动地址&#xff1a;点此直达 二、华为云双11…

数据结构——双向链表的实现

一、双向链表的结构 注意&#xff1a;双向链表又称带头双向循环链表 这⾥的“带头”跟前⾯我们说的“头节点”是两个概念&#xff0c;实际前⾯的在单链表阶段称呼不严 谨&#xff0c;但是为了同学们更好的理解就直接称为单链表的头节点。 带头链表⾥的头节点&#xff0c;实际…

halcon canny 和opencv c++ canny 实现对比

Opencv和C实现canny边缘检测_opencv边缘增强-CSDN博客 一、canny实现步骤 1、图像必须是单通道的&#xff0c;也就是说必须是灰度图像 2、图像进行高斯滤波&#xff0c;去掉噪点 3、sobel 算子过程的实现&#xff0c;计算x y方向 、梯度&#xff08;用不到&#xff0c;但是…