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屬性可以避免生成一張中間表。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM