jpa的一些个人总结(多表查询的坑)
1 jpa中多表连接的坑
先说结论:jpa中多表查询如果用一对一、多对一、多对多注解,则有两种方式,一种为有中间表,一种没有。
有中间表的主表没有外键,外键在关联表中(关联表中关联主表的主键)。有中间表的好处是主表没有外键,方便。
如果没有中间表,那就纯用一对一、多对一、多对多注解,通过mappedby注解来告诉jpa不生成关联表,此时主表中必须手动进行书写外键(因为没有中间表)。
总结:用一对一、多对一、多对多注解,相当于把要查的结果以对象属性的方式直接镶嵌到对象中。查询的时候直接用对象的get()方法,就可以得到关联的属性信息;同理,修改的时候可以直接修改这部分属性。不需要关心SQL语句。jpa帮你自动解决。
如果不用一对一、多对一、多对多注解,那么只能手动进行书写sql语句,添加@Query注解,同时加上nativeQuery = true属性即可写原生sql语句。
此时多表查询通过sql语句进行多表链接,把查询到的结果输出即可。
2 @JoinColumn的坑
先看表结构:
主表结构
sys_render(id,name,enabled)
sys_dept(dept_id,....)
sys_job(job_id,.....)
render(租客) dept(部门) job(岗位)三者关系均为多对多
关联表结构
sys_renders_dept(render_id,dept_id)
sys_renders_jobs(render_id,job_id)
我所作的需求是:通过中间表的形式进行CRUD的逻辑。
直接看正确的@joinColumn书写形式(在render对象中):
@ManyToMany(fetch = FetchType.EAGER)
@ApiModelProperty(value = "用户岗位")
@JoinTable(name = "sys_renders_jobs", joinColumns = { @JoinColumn(name = "render_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "job_id", referencedColumnName = "job_id") })
private Set<Job> jobs;
@ManyToMany(fetch = FetchType.EAGER)
@ApiModelProperty(value = "部门信息")
@JoinTable(name = "sys_renders_depts", joinColumns = { @JoinColumn(name = "render_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "dept_id", referencedColumnName = "dept_id") })
private Set<Dept> depts;
一定要注意,referencedColumnName这个属性指的是render的id,而第一个name的render_id是关联表(sys_renders_jobs)的第一列(坑就在这,一定不要弄反了);
同理,inverseJoinColumns中的referencedColumnName指的是job表中的job_id,第一个name指的是关联表(sys_renders_jobs)的第二列。
3 贴出@mappedBy注解的详细使用方式
mappedBy:
1>只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
2>mappedBy标签一定是定义在被拥有方的,他指向拥有方;
3>mappedBy的含义,应该理解为,拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以做到的;
4>mappedBy跟joinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy这方定义JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表。
mappedBy表示声明自己不是一对多的关系维护端,由对方来维护,是在一的一方进行声明的。mappedBy的值应该为一的一方的表名。
例如:城市与大学,一个城市有多个大学。
在City实体类中
@OneToMany(mappedBy="city")
@Cascade(CascadeType.ALL)
private List
@mappedBy注解的作用:在JPA中,在@OneToMany里加入mappedBy属性可以避免生成一张中间表。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构