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