MyBatis 学习(五)之 高级映射

目录

1 association 和 collection 介绍

2 案例分析

3 一对一关联和一对多关联

4 参考文档


1 association 和 collection 介绍

        在之前的 SQL 映射文件中提及了 resultMap 元素的 association collection 标签,这两个标签是用来关联查询的,它们的属性几乎一致,以下是对它们属性的描述,红色标注的是常用属性。

属性描述
property实体类属性名
column数据库字段名或者其别名
javaType实体类属性的 Java 类型
jdbcType数据库列的数据类型
ofType指定关联对象的类型。它通常用于泛型类型的情况,以确保正确的类型转换
select指定一个子查询,用于加载关联的对象
fetchType用于控制加载策略,比如立即加载还是延迟加载。常见的取值有 lazy(延迟加载)和 eager(立即加载)
resultMap引用预定义的结果映射,以便更灵活地配置关联对象的映射规则
resultSet指定结果集的名称,以便在多结果集的情况下进行区分
autoMapping是否自动映射所有列到目标对象的属性上。默认为 true,表示自动映射;设置为 false 则表示不自动映射
columnPrefix当使用内连接查询时,这个属性可以用来指定前缀,以区分关联表的列名
foreignColumn指定外键对应的列名
notNullColumn指定一个列名,只有当该列的值不为 null 时,才会执行关联查询
typeHandler自定义的类型处理器

2 案例分析

以典型的 员工 (Employee) 和部门 (Department) 为例

  • 一个员工只能在一个部门:Employee -> Department(一对一)
  • 一个部门可以包含多个员工:Department -> Employee(一对多)

以用户 (User) 和角色 (Role) 为例,两者成了一个双向的一对多,从而变成了多对多,不做介绍

  • 一个用户可以拥有多个角色:User -> Role(一对多)
  • 一个角色可以赋予多个用户:Role -> User(一对多)

表 department 和 表 employee

# 创建 department 表
drop table if exists department;
create table department(
department_id int(11) primary key auto_increment, #主键,自增
department_name varchar(255)
)charset=utf8;# 插入数据
insert into department(department_name) values
('开发部'),
('人力资源部'),
('市场营销部'),
('财务部'),
('行政部'),
('监察部'),
('客服服务部');# 创建 employee 表
drop table if exists employee;
create table employee(
employee_id int(11) primary key auto_increment, #主键,自增
employee_name varchar(255),
employee_age int(11),
employee_sex char(32),
employee_email varchar(255),
employee_address varchar(255),
department_id int(11)
)charset=utf8;# 插入数据
insert into employee values
(1, '唐浩荣', 23, 1, '15477259875@163.com', '中国上海浦东区', 1),
(2, '黄飞鸿', 32, 1, '86547547@qq.com', '大清广东', 2),
(3, '十三姨', 18, 0, '520520520@gmail.com', '大清广东', 3),
(4, '纳兰元述', 28, 1, '545627858@qq.com', '大清京师', 5),
(5, '梁宽', 31, 1, '8795124578@qq.com', '大清广东', 7),
(6, '蔡徐坤', 20, 0, '4257895124@gmail.com', '四川成都', 4),
(7, '杨超越', 21, 0, '8746821252@qq.com', '中国北京', 7),
(8, '马保国', 66, 1, '6666666666@qq.com', '广东深圳', 6),
(9, '马牛逼', 45, 1, 'asdfg45678@163.com', '湖北武汉', 3);

3 一对一关联和一对多关联

工程目录

Department 类

public class Department {//部门idprivate Integer deptId;//部门名称private String deptName;//部门有哪些员工private List<Employee> employees;// Getter、Setter、toString 方法省略
}

Employee 类

public class Employee {//员工idprivate Integer empId;//员工名称private String empName;//员工年龄private Integer empAge;//员工性别private Integer empSex;//员工邮箱private String empEmail;//员工地址private String empAddress;//员工所属部门,和部门表构成一对一的关系,一个员工只能在一个部门private Department department;// Getter、Setter、toString 方法省略
}

创建 DepartmentMapper

public interface DepartmentMapper {//查询所有数据@Select("select * from department")@Results(id = "deptMap1", value = {@Result(property = "deptId", column = "department_id"),@Result(property = "deptName", column = "department_name"),// 一对多关联对象// 根据 department_id 来比较@Result(property = "employees", column = "department_id",many = @Many(select = "com.mapper.EmployeeMapper.selectEmpByDeptId"))})List<Department> selectAll();// 根据 id 查找部门@Select("select * from department where department_id = #{id}")@Results(id = "deptMap2", value = {@Result(property = "deptId", column = "department_id"),@Result(property = "deptName", column = "department_name")})Department findDepartmentById(int id);
}

创建 EmployeeMapper

public interface EmployeeMapper {//查询所有数据@Select("select * from employee")@Results(id = "empMap1", value = {@Result(property = "empId", column = "employee_id", id = true),@Result(property = "empName", column = "employee_name"),@Result(property = "empAge", column = "employee_age"),@Result(property = "empSex", column = "employee_sex"),@Result(property = "empEmail", column = "employee_email"),@Result(property = "empAddress", column = "employee_address"),// 一对一关联对象// 根据 department_id 来比较@Result(property = "department", column = "department_id",one = @One(select = "com.mapper.DepartmentMapper.findDepartmentById"))})List<Employee> selectAll();//根据员工id查询数据@Select("select * from employee where employee_id = #{id}")@ResultMap("empMap1")Employee selectEmpByEmpId(@Param("id") int empId);// 根据 department_id 查询数据@Select("select * from employee where department_id = #{id}")@ResultMap("empMap1")Employee selectEmpByDeptId(@Param("id") int deptId);
}

log4j.properties

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

mysql.properties

url=jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
name=root
password=123456
driver=com.mysql.cj.jdbc.Driver

MyBatis 配置文件 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><!-- 通过properties标签,读取java配置文件的内容 --><properties resource="mysql.properties" /><!-- 配置环境.--><environments default="development"><environment id="development"><!--配置事务的类型--><transactionManager type="JDBC"></transactionManager><!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 --><dataSource type="POOLED"><!--配置连接数据库的4个基本信息--><property name="url" value="${url}" /><property name="username" value="${name}" /><property name="password" value="${password}" /><property name="driver" value="${driver}" /></dataSource></environment></environments><!--通过包 package 引入 SQL 映射文件--><mappers><package name="com.mapper"/></mappers>
</configuration>

创建 EmployeeTest 测试类

public class EmployeeTest {//定义 SqlSessionSqlSession sqlSession = null;//定义 EmployeeMapper 对象private EmployeeMapper mapper = null;@Beforepublic void getSqlSession() throws IOException {//加载 mybatis 全局配置文件 Resources// 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//创建 SqlSessionFactory 对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);//根据 sqlSessionFactory 产生 sessionsqlSession = sqlSessionFactory.openSession();// 创建Mapper接口的的代理对象,getMapper方法底层会通过动态代理生成 EmployeeMapper 的代理实现类mapper = sqlSession.getMapper(EmployeeMapper.class);}//查询所有员工数据@Testpublic void testSelectAll() {List<Employee> listEmployee = mapper.selectAll();for (Employee employee : listEmployee) {System.out.println(employee);}sqlSession.close();}//根据员工 id 查询数据@Testpublic void testSelectById() {Employee employee = mapper.selectEmpByEmpId(1);System.out.println(employee);sqlSession.close();}
}

测试结果

查询所有员工数据,包括员工所在部门(一个员工属于一个部门)

创建 DepartmentTest 测试类

public class DepartmentTest {//定义 SqlSessionSqlSession sqlSession = null;//定义 DepartmentMapper 对象private DepartmentMapper mapper = null;@Beforepublic void getSqlSession() throws IOException {//加载 mybatis 全局配置文件 Resources// 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//创建 SqlSessionFactory 对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);//根据 sqlSessionFactory 产生 sessionsqlSession = sqlSessionFactory.openSession();// 创建Mapper接口的的代理对象,getMapper方法底层会通过动态代理生成 DepartmentMapper 的代理实现类mapper = sqlSession.getMapper(DepartmentMapper.class);}//查询所有部门数据@Testpublic void testSelectAll() {List<Department> listDepartment = mapper.selectAll();for (Department department : listDepartment) {System.out.println(department);}sqlSession.close();}//根据部门 id 查询 数据@Testpublic void testSelectById() {Department department = mapper.findDepartmentById(1);System.out.println(department);sqlSession.close();}
}

测试结果

查询所有部门信息,包括该部门有哪些员工(一个部门有多个员工)

4 参考文档

篇篇“参考”这位博主的文档。。。不过确实写的挺好的

Mybatis3详解(八)----高级映射之一对一映射 - 唐浩荣 - 博客园 (cnblogs.com)

Mybatis3详解(九)----高级映射之一对多映射 - 唐浩荣 - 博客园 (cnblogs.com)

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

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

相关文章

算法--时空复杂度分析以及各个数据量对应的可使用的算法(C++;1s内)

这里写目录标题 由数据范围反推算法时间复杂度以及算法内容分析时间复杂度看循环实例1实例2 固定时间复杂度快排和归并排序二分高精度算法双指针算法单链表插入删除操作栈和队列的操作单调栈和单调队列KMPTire并查集堆哈希表BFS、DFS图的深度优先、宽度优先遍历dijkstra算法朴素…

瑞_Redis_Redis的Java客户端

文章目录 1 Redis的Java客户端1.1 Jedis快速入门1.1.1 入门案例1.1.1.1 项目构建1.1.1.2 引入依赖1.1.1.3 建立连接1.1.1.4 释放资源1.1.1.5 测试1.1.1.6 完整测试类代码 1.1.2 Jedis连接池1.1.2.1 连接池工具类1.1.2.2 改造原始代码 &#x1f64a; 前言&#xff1a;本文章为瑞…

常用sql语句及其优化

文章目录 介绍常用sql语句1. 数据查询1.1 SELECT 语句1.2 DISTINCT 关键字1.3 WHERE 子句1.4 ORDER BY 子句1.5 LIMIT 关键字 2. 数据更新2.1 INSERT INTO 语句2.2 UPDATE 语句2.3 DELETE FROM 语句 3. 数据管理3.1 CREATE TABLE 语句3.2 ALTER TABLE 语句3.3 DROP TABLE 语句 …

批量自动加好友神器!微信快速扩友秘籍!

对于一些个人或者企业来说&#xff0c;传统的人工添加好友方式往往会出现效率低下&#xff0c;费时费力的问题。那么&#xff0c;有没有一种快速、便捷、安全的方式来解决这个问题呢&#xff1f;答案当然是肯定的&#xff0c;那就是通过使用微信管理系统来解决这一问题。 在微…

基于java+springboot景区行李寄存管理系统设计和实现

基于javaspringboot景区行李寄存管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取…

5GC SBA架构

协议标准&#xff1a;Directory Listing /ftp/Specs/archive/23_series/23.501/ (3gpp.org) NF描述说明NSSFNetwork Slice Selection Function网络切片选择&#xff0c;根据UE的切片选择辅助信息、签约信息等确定UE允许接入的网络切片实例。NEF Network Exposure Function网络开…

疾控中心的污水采样瓶用的是什么材质

疾控中心的污水采样瓶采用的材质是聚乙烯或聚丙烯塑料。这种材质的污水采样瓶具有耐腐蚀、耐高压、无毒无味、重量轻、易于携带等优点。此外&#xff0c;这种材质的污水采样瓶还可以在高温下消毒&#xff0c;不会变形或破裂。 疾控中心的污水采样瓶通常有不同的容积和形状&…

Harbor高可用(haproxy和keepalived)

Harbor高可用&#xff08;haproxy和keepalived&#xff09; 文章目录 Harbor高可用&#xff08;haproxy和keepalived&#xff09;1.Harbor高可用集群部署架构1.1 主机初始化1.1.1 设置网卡名和ip地址1.1.2 设置主机名1.1.3 配置镜像源1.1.4 关闭防火墙1.1.5 禁用SELinux1.1.6 设…

SpringBoot 自定义映射规则resultMap association一对一

介绍 例&#xff1a;学生表&#xff0c;班级表&#xff0c;希望在查询学生的时候一起返回该学生的班级&#xff0c;而一个实体类封装的是一个表&#xff0c;如需要多表查询就需要自定义映射。 表结构 班级表 学生表 SQL语句 SELECT a.id,a.name,a.classes,b.id classes…

Charles抓包 - 安装、激活、证书配置

最近刚好又遇到了抓包的需求&#xff0c;之前一直使用 Fiddler 抓包&#xff0c;这几年一直听大家都在用 Charles 抓包&#xff0c;正好一起了解下&#xff08;一般建议掌握一种抓包方式即可&#xff0c;都可以解决同种需求场景&#xff09; 抓包 Fiddler抓包 Charles 下载、安…

2024年新提出的算法|LEA爱情进化算法(Love Evolution Algorithm)

Love Evolution Algorithm: a stimulus–value–role theory-inspired evolutionary algorithm for global optimization 爱情进化算法Love Evolution Algorithm&#xff0c;LEA&#xff0c;于2024年2月发表在中科院3区SCI期刊 The Journal of Supercomputing。 1、简介 本文提…

幸运星数(爷再也不想用pow了)

解法&#xff1a; 暴力 #include <iostream> #include <vector> using namespace std; #define endl \nint main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int n;long long sum 0, a;cin >> n;for (int i 1; i < n; i) {a 1;for (in…

蓝桥杯刷题2

1. 修建灌木 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);int n scan.nextInt();for (int i 1;i < n1;i){int distance Math.max(i-1,n-i);System.out.println(distance*2);}scan.close…

种花

分情况&#xff1a; 第一盆k种选择&#xff0c;之后全部k-1种选择 每次相乘结果对1e97取模 #include <iostream> #include <vector> #include <algorithm> using namespace std; #define endl \n const int N 1e9 7;int main() {ios::sync_with_stdio(f…

微信小程序iOS禁止上下拉显示白边

先上图暴露出问题 iOS端这个页面明明正好显示的&#xff0c;非要能下拉上拉给显示出来点白边。这样不就不好看了嘛。。 想了想是不是支持页面下拉导致的&#xff0c;加入以下代码到json文件中。 {"enablePullDownRefresh": false,"usingComponents": {} }…

java009 - Java面向对象基础

1、类和对象 1.1 什么是对象 万物皆对象&#xff0c;客观存在的事物皆为对象。 1.2 什么是面向对象 1.3 什么是类 类是对现实生活中一类具有共同属性和行为的事物抽象。 特点&#xff1a; 类是对象的数据类型类是具有相同属性和行为的一组对象的集合 1.4 什么是对象的属…

project.config.json 文件内容错误] project.config.json: libVersion 字段需为 string, string

家人们&#xff0c;遇到了一个新的报错 于是从网上找了各种方法&#xff0c;有说把开发者工具关闭重启的&#xff0c;有说开发者工具下载重新下载的&#xff0c;有说开发者工具路径安装得在C盘的&#xff0c;均没有效果 解决方法&#xff1a; 1、运行项目&#xff0c;在开发者…

好的测试数据管理,到底要怎么做?

你的组织是否实施了测试数据管理&#xff1f;如果你的组织处理关键或敏感的业务数据&#xff0c;测试数据管理肯定会让组织受益。与测试数据相关的问题占所有软件缺陷的 15%&#xff0c;这一事实强调了测试数据的重要性。本文将准确讨论测试数据经理职责、测试数据经理需要什么…

java-ssm-jsp广播剧制作订阅系统

java-ssm-jsp广播剧制作订阅系统 获取源码——》公主号&#xff1a;计算机专业毕设大全

13.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-如果没有工具就创造工具

内容参考于&#xff1a; 易道云信息技术研究院VIP课 上一个内容 &#xff1a;12.游戏网络通信存在的问题 现在把游戏网络的架构看了一个小小的大概&#xff0c;可以用它的接口发数据接收数据了&#xff0c;如果真正想用它这一套东西&#xff0c;真正核心不在于它的接口而在于…