MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询
MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询
MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询
com.github.dreamyoung mprelation 0.0.3.2-RELEASE
注解工具使用优缺点:
优点:
使用简单,通过在实体类上添加@OneToOne / @OneToMany / @ManyToOne / @ManyToMany 等注解即可。
注解命名参考了Hibernate命名,如果使用过Hibernate则即刻可上手。
1对1、1对多、多对1、多对多映射时,可以不再写SQL及XML配置文件,免去配置冗长的的麻烦。
Service层及Mapper层不需要再添加 getLinkById 、 selectLinkById 之类的方法来关联映射
重写过的ServiceImpl各种内置的查询方法都自动关联查询,非内置方法可以调用autoMapper相关方法进行自动或手动关联
所有执行采用非join方式查询,同时解决关联处理的1+n问题
1
2
3
4
5
6
7
8
9
10
11
缺点:
目前只针对SqlSession/Mappe形式有效(ActiveRecord形式暂未涉及修改,也没有测试)
非事务下, 1个连接(1个SqlSession)只执行一条SQL,而自动获取每个关联属性的sql都会创建12个SqlSession(并执行12条SQL)。如果需要使用非内置方法(即除ServiceImpl外的方法),必须配置只读事务来减少SqlSession创建。
如果有多个延迟加载的关联属性,类上可注解@AutoLazy(false)或没有标注该注解(默认),之后通过initialize方法在事务范围内的一个SqlSession中同时加载需要的多个延迟加载的属性。
1
2
3
4
5
使用注意点:
非ServiceImpl内置的业务查询,配置事务管理,减少SqlSession的创建。
实体上可用注解@AutoLazy(true/false)来标注是否自动触发延迟加载,该注解只针对需要延迟的属性。
★ true或无值的话,则获取延迟的关联属性时自动关联。但每一个延迟属性的获取都消耗一个SqlSession。适合于只有一个延迟属性的情况。★ false或者不标注该注解的话,需要手动通过initialize()方法对延迟的关联属性进行获取,否则不会自动关联获取,此时关联为空。适合于有多个延迟属性的情况。
如果可以,不使用延迟加载(延迟加载的使用是在SqlSession关闭后执行的,需要重新创建SqlSession)。
如果确实需要延迟加载,可使用ServiceImpl 或 AutoMapper 相关的initialize方法一次性加载所有需要的被延迟的属性(只需要创建额外的一个SqlSession,毕竟SqlSession之前已经关闭)
1
2
3
4
5
6
7
8
9
10
11
注解使用:
一对多(多对一) :
Company实体类中配置:
复制代码
@Data
public class Company {
@TableId(value = “company_id”)
private Long id;
private String name;
//一对多
@TableField(exist = false)
@OneToMany //一对多默认为延迟加载,即@Lazy/@Lazy(true)/或此时不标注
@JoinColumn(name=“company_id”,referencedColumnName = “company_id”)//@TableId与一方相关属性中@TableField名称保持一致时@JoinColumn可省略
private Set employees;
1
2
3
4
5
}
Man实体类中配置:
@Data
public class Man {
@TableId(value = “man_id”)
private Long id;
private String name;
//多对一
@TableField(“company_id”)
private Long companyId;
@TableField(exist = false)
@ManyToOne //多对一默认为立即加载,即@Lazy(false)或此时不标注
@JoinColumn(name = “company_id”, referencedColumnName = “company_id”) //相关的@TableField与多方的@TableId名称一致时@JoinColumn可省略
private Company company;
1
2
3
4
5
6
7
8
9
10
11
12
}
一对多(多对一)表结构: company: (compnay_id, name) man: (man_id, name, company_id)
一对一:
Woman实体类配置:
@Data
public class Woman {
@TableId(value = “woman_id”)
private Long id;
private String name;
//一对一
@TableField(“lao_gong_id”)
private Long laoGongId;
@TableField(exist = false)
@OneToOne //一对一默认为立即加载,即@Lazy(false)或此时不标注
@JoinColumn(name = “lao_gong_id”, referencedColumnName = “man_id”)
private Man laoGong;
1
2
3
4
5
6
7
8
}
Man实体类配置:
@Data
public class Man {
@TableId(value = “man_id”)
private Long id;
private String name;
//一对一
@TableField(“lao_po_id”)
private Long laoPoId;
@TableField(exist = false)
@OneToOne
@JoinColumn(name = “lao_po_id”, referencedColumnName = “woman_id”)
private Woman laoPo;
1
2
3
4
5
6
7
8
}
一对一表结构:(实际可以减少一方) woman: (woman_id, name, lao_gong_id) man: (man_id, name, lao_po_id)
多对多:
Course实体类配置:
@Data
public class Course {
@TableId(value = “course_id”)
private Long id;
private String name;
//多对多
@TableField(exist = false)
@ManyToMany //多对多默认为延迟加载,即@Lazy(true)或此时不标注
@JoinTable(targetMapper = StudentCourseMapper.class) //第三方命名为StudentCourseMapper或CourseStudentMapper时@JoinTable注解一般可省略
@JoinColumn(name = “course_id”, referencedColumnName = “course_id”)
@InverseJoinColumn(name = “child_id”, referencedColumnName = “student_id”)
private List students;
1
2
3
4
5
6
7
}
Child实体类配置:
@Data
public class Child {
@TableId(“child_id”)
private Long id;
private String name;
//多对多
@TableField(exist = false)
@ManyToMany
@JoinTable(targetMapper=StudentCourseMapper.class)
@JoinColumn(name = “child_id”, referencedColumnName = “student_id”)
@InverseJoinColumn(name = “course_id”, referencedColumnName = “course_id”)
private List courses;
1
2
3
4
5
6
7
}
StudenCourse中间类(多对多必须要有,如果命名为StudentCourse或CourseStudent,则上边的@JoinTable可省略):
@Data
public class StudentCourse {
//可以有也可以无此ID
private Long id;
@TableField(“student_id”)
private Long studentId;
@TableField(“course_id”)
private Long courseId;
1
2
3
4
5
}
多对多表结构:course: (course_id, name) child: (child_id, name) student_course:(id, student_id, course_id)
mprelation 关联查询,使用过程:
POM中引入mprelation:
com.github.dreamyoung mprelation 0.0.3.2-RELEASE
配置 AutoMapper (只要是扫描被注解的实体类)
@Configuration
public class AutoMapperConfig {
@Bean
public AutoMapper autoMapper() {
return new AutoMapper(new String[] { “demo.entity”,“demo.bean” }); //配置实体类所在目录(可多个,暂时不支持通过符*号配置)
}
}
在实体类中配置注解(更多的注解配置见上边注解部分,这里只列出其中一个)
@Data
@AutoLazy //不需要手动触发加载延迟属性,当延迟属性被调用时自动创建Session进行获取。可见如果有多个延迟属性需要被使用时,会造成多次创建Session,此时可以标注为AutoLazy(false)或不标注,然后采用initialze方法手动一次性加载需要的属性
public class Man {
@TableId(value = “man_id”)
private Long id;
private String name;
private Long laoPoId;
@TableField(exist = false)
@OneToOne
@JoinColumn(name = “lao_po_id”, referencedColumnName = “woman_id”)
private Woman laoPo;
@TableField(“company_id”)
private Long companyId;
@TableField(exist = false)
@ManyToOne
@JoinColumn(name = “company_id”, referencedColumnName = “company_id”)
private Company company;
@TableField(exist = false)
@OneToMany
@JoinColumn(name = “man_id”, referencedColumnName = “lao_han_id”)
@Lazy(false)
private List waWa;
@TableField(exist = false)
@OneToMany
@JoinColumn(name = “man_id”, referencedColumnName = “man_id”)
@Lazy(false)
private Set tels;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
}
在Service层、Mapper层的使用,见下面:
以下是基于Mybatis-Plus官方示例修改而来的测试程序:
通过继承工具类重写过的IService / ServiceImpl 会自动执行关联映射, 无须再写gettLinkById之类的方法(可以使得各实现类没有任何方法):
mapper接口:
public interface ManMapper extends BaseMapper {}
service接口:
public interface IManService extends IService {} // IService为重写过的同名接口
Service实现:
@Service
public class ManServiceImpl extends ServiceImpl<ManMapper, Man> implements IManService {} // ServiceImpl为重写过的同名接口
测试调用:
public class ServiceTest {
@Autowired
ManService manService;
@Test
public void t_man_serviceImpl() {
Man man = manService.getById(1); // 原Mybatis-Plus的ServiceImpl的各种查询,被重写过后,都可以自动关联,
System.out.println(man);
}
1
2
3
4
5
}
结果输出:
Man(
id=1,
name=程序猿小明,
laoPoId=1,
laoPo=Woman(id=1, name=程序猿小明老婆, laoGongId=1, laoGong=null, waWa=null),
companyId=1,
company=Company(id=1, name=百度, employees=null),
waWa=[
Child(id=1,name=xxx1,lao_han_id=null, laoHan=null, lao_ma_id=null, laoMa=null, courses=null),
Child(id=2,name=xxxx2, lao_han_id=null, laoHan=null, lao_ma_id=null, laoMa=null, courses=null)
],
tels=[
Tel(id=1, tel=139xxxxxx, manId=1, laoHan=null),
Tel(id=4, tel=159xxxxxx, manId=1, laoHan=null),
Tel(id=2, tel=137xxxxxx, manId=1, laoHan=null)
]
)
如需需要对其关联属性对象的关联属性进行自动加载,可以继续使用AutoMapper对象的mapperEntity、mapperEntityList、mapperEntitySet、mapperEntityPage来操作:
比如想获取(填充)waWas 的关联,则:
List waWas=man.getWaWas();
autoMapper.mapperEntityList(waWas);
AutoMapper类中的几个常用方法说明:
mapperEntity(entity) 可以对一个实体类,实现自动关联。
mapperEntityList(entity_list) 可以对一个实体类List,实现自动关联。
mapperEntitySet(entity_set) 可以对一个实体类Set,实现自动关联。
mapperEntityCollection(entity_list_or_set) 可以对一个实体类Set或List,实现自动关联。
mapperEntityPage(entity_page) 可以对一个实体类Page,实现自动关联。
mapper(entity_entityListOrSet_entityPage) 统一上边的各种方法,直接对实体类,列表,分页都可以实现自动关联。
initialize(entity/entityList/entitySet/entityPage, OneOrMoreLazyPropertyName …)
可以对一个实体类/实体类List/实体类Set/实体类Page,在事务范围内,手动立即触发其各个被@Lazy(true)标注的关联属性。
该方法在重写过的ServiceImpl内也存在(供Controller层调用来加载延迟关联的属性)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
AutoMapper在重写过的ServiceImpl类中已经自动注入可用(名为autoMapper),其它情况也可以手动注入:
public class MPRTest2 {
@Autowired
AutoMapper autoMapper;
@Resource
private ManMapper manMapper;
@Test
public void t_man() {
Man man = manMapper.selectById(1L);
autoMapper.mapperEntity(man);
System.out.println(man);
}
1
2
3
4
5
6
7
8
9
}
————————————————
版权声明:本文为CSDN博主「He少年」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vsmybits/article/details/123995224
相关文章:
MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询
MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询 MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询 com.github.dreamyoung mprelation 0.0.3.2-RELEASE 注解工具使用优缺点: 优点: 使用简单…...

arcgis javascript api4.x加载天地图web墨卡托(wkid:3857)坐标系
效果: 示例代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&quo…...

中职组安全-win20230217-环境-解析
*任务说明: 仅能获取win20230217的IP地址 用户名:test,密码:123456 访问服务器主机,找到主机中管理员名称,将管理员名称作为Flag值提交; john 访问服务器主机,找到主机中补丁信息,将补丁编号作为Flag值提交ÿ…...

PMP学习考试经验总结
PMP备考日程计划表 我的PMP的备考大概花了三个月的时间, 可以分为以下几个阶段: Week 1-4: 读完PMBoK 前面7个知识领域(中英文版PMBoK一起看)。每看完一个知识领域,就看参考书里面的相应章节(汪博士那本)…...

leetcode206.反转链表
https://leetcode.cn/problems/reverse-linked-list/description/ 题目 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入&am…...
python每日学17:控制推导逻辑的子表达式不要超过两个
背景:今天放假在家,《python学习手册》不在身边,所以今天学习《Effective Python: 编写高质量Python代码的90个有效方法》第28条《控制推导逻辑的子表达式不要超过两个》,这本书已经是第二版了,第一版是《编写高质量py…...
地质时间与数值模拟时间转换(mm/Ma-->m/s)
一百万年(1Ma)等于315,576,000,0003.15576e11秒。 计算方法如下: 一年通常定义为365天(非闰年)。每天有24小时。每小时有60分钟。每分钟有60秒。 所以,一年的秒数为: 365天 24小时/天 60分钟/小时 60秒/分钟 31…...
linux文件描述符管理
在实际的项目开发中,文件描述符是经常用到的并且在释放资源过程中也是很容易忽略的,使用之后不释放就会增加cpu负担,无异于内存泄漏;所以时刻掌握文件描述符的状态是非常重要的!下面介绍文件描述符的管理方法。 1. 文…...
谷歌翻译不能使用 host添加IP
谷歌浏览器翻译不能使用解决教程_142.250.100.90 translate.googleapis.com-CSDN博客...

Redis命令 - Lists命令组常用命令
先创建一个 key 叫做 mylist,mylist存一个list。 list数据类型底层是一个链表。先进后出,后进先出。 命令中的L(Left)、R(Right)代表链表的头部L(下标0的位置)和尾部R(…...

切分大文件sql为小份
数据库太大了,整个备份导入出问题或者慢,需要将整个库按照表分割(一个表一个sql文件) 环境 win10 工具:python3.7pycharm 要分割的文件大小:6G,sql文件import redbname with open(best**.sql,…...

最新版CleanMyMac X4.14.7智能清理mac磁盘垃圾工具
CleanMyMac X是一款专业的Mac清理软件,可智能清理mac磁盘垃圾和多余语言安装包,快速释放电脑内存,轻松管理和升级Mac上的应用。同时CleanMyMac X可以强力卸载恶意软件,修复系统漏洞,一键扫描和优化Mac系统,…...
数据割据:当代社会数据治理的挑战
数据割据是指各个组织、企业或政府机构在数据的采集、存储和使用上形成了相对独立的局面,彼此之间缺乏有效的数据共享和流通机制。这种割据现象导致了数据的重复采集、冗余存储以及信息孤岛的出现,不仅浪费了大量的资源,还制约了数据的价值发…...

逻辑回归(解决分类问题)
定义:逻辑回归是一种用于解决分类问题的统计学习方法。它通过对数据进行建模,预测一个事件发生的概率。逻辑回归通常用于二元分类问题,即将数据分为两个类别。它基于线性回归模型,但使用了逻辑函数(也称为S形函数&…...

论文阅读:Feature Refinement to Improve High Resolution Image Inpainting
项目地址:https://github.com/geomagical/lama-with-refiner 论文地址:https://arxiv.org/abs/2109.07161 发表时间:2022年6月29日 项目体验地址:https://colab.research.google.com/github/advimman/lama/blob/master/colab/LaMa…...

结构型设计模式——适配器模式
适配器模式 这个更加好理解,就是做适配功能的类,例如,现在手机没有了圆形耳机接口,只有Type-C接口,因此你如果还想要使用圆形耳机的话需要买个圆形接口转Type-C的转换器(适配器),这…...

三菱FX系列PLC定长切割控制(线缆裁切)
三菱PLC绝对定位指令DDRVA实现往复运动控制详细介绍请查看下面文章链接: https://rxxw-control.blog.csdn.net/article/details/135570157https://rxxw-control.blog.csdn.net/article/details/135570157这篇博客我们介绍线缆行业的定长切割控制相关算法。 未完待…...

GPT编程:运行第一个聊天程序
环境搭建 很多机器学习框架和类库都是使用Python编写的,OpenAI提供的很多例子也是Python编写的,所以为了方便学习,我们这个教程也使用Python。 Python环境搭建 Python环境搭建有很多种方法,我们这里需要使用 Python 3.10 的环境…...

NLP论文阅读记录 - WOS | ROUGE-SEM:使用ROUGE结合语义更好地评估摘要
文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结 前言 ROUGE-SEM: Better evaluation of summarization using ROUGE combin…...

vscode 创建文件自动添加注释信息
随机记录 目录 1. 背景介绍 2. "Docstring Generator"扩展 2.1 安装 2.2 设置注释信息 3. 自动配置py 文件头注释 1. 背景介绍 在VS Code中,您可以使用扩展来为新创建的Python文件自动添加头部注释信息。有几个常用的扩展可以实现此功能࿰…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
[QMT量化交易小白入门]-六十二、ETF轮动中简单的评分算法如何获取历史年化收益32.7%
本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。 QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。 文章目录 相关阅读1. 策略概述2. 趋势评分模块3 代码解析4 木头…...

C++课设:实现本地留言板系统(支持留言、搜索、标签、加密等)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、项目功能概览与亮点分析1. 核心功能…...