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 college;

@mappedBy注解的作用:在JPA中,在@OneToMany里加入mappedBy属性可以避免生成一张中间表。

posted @ 2021-09-10 17:09  吾心似秋月666  阅读(1575)  评论(0编辑  收藏  举报