問題描述:稿件附件表數據時出現多條重複數據。sql
介紹:數據庫
表:稿件實體Manuscripts (數據庫表MANUSCRIPTS),稿件附件實體ManuscriptsAtt(表MANUSCRIPTS_ATT),稿件審覈實體:ManuscriptsQuotesfetch
表關係:稿件與稿件附件 一對多;稿件與稿件審覈一對多;this
代碼:spa
稿件實體 Manuscripts :code
@Entity
@Table(name = "MANUSCRIPTS")blog
public class Manuscripts implements Serializable { //主鍵 @Id @Column(length = 38,name = "ID") private String id; ...... @OneToMany(targetEntity = ManuscriptsAtt.class,fetch=FetchType.EAGER) @JoinColumn(name="MANUSCRIPTS_ID") @Fetch(FetchMode.SUBSELECT) private Set<ManuscriptsAtt> manuscriptsAtts; @OneToMany(targetEntity = ManuscriptsQuotes.class,fetch=FetchType.EAGER) @JoinColumn(name="MANUSCRIPTS_ID") @Fetch(FetchMode.SUBSELECT) private Set<ManuscriptsQuotes> manuscriptsQuotes; ...... }
稿件附件實體: ip
@Entity
@Table(name = "MANUSCRIPTS_ATT")get
public class ManuscriptsAtt implements Serializable { /** * */ private static final long serialVersionUID = 1L; //主鍵 @Id @Column(length = 38, name = "ID") private String id; ..... //父類 @ManyToOne @JoinColumn(name = "MANUSCRIPTS_ID") private Manuscripts manuscripts; .....}
稿件審覈實體:it
@Entity @Table(name = "MANUSCRIPTS_QUOTES") public class ManuscriptsQuotes implements Serializable { /** * */ private static final long serialVersionUID = 1L; //主鍵 @Id @Column(length = 38,name = "ID") private String id; //父類 @ManyToOne @JoinColumn(name = "MANUSCRIPTS_ID") private Manuscripts manuscripts; ... }
稿件實體 Manuscripts 中oneToMany 下Fetch設置不一樣結果不一樣
@Fetch(FetchMode.JOIN) 會使用left join查詢 只產生一條sql語句
@Fetch(FetchMode.SELECT) 會產生N+1條sql語句
@Fetch(FetchMode.SUBSELECT) 產生兩條sql語句 第二條語句使用id in (…..)查詢出全部關聯的數據
下面介紹列出附件數據sql和會出現結果
@Fetch(FetchMode.JOIN) 後sql語句和結果(會使用left join查詢 只產生一條sql語句)
Hibernate: select this_.id as id1_13_1_, this_.file_address as file_add6_13_1_, this_.file_name as file_nam7_13_1_, this_.manuscripts_id as manuscr11_13_1_, this_.type as type9_13_1_, manusc1_.id as id1_11_0_, manusc1_.content as content4_11_0_, manusc1_.create_time as create_t5_11_0_, manusc1_.title as title21_11_0_, manusc1_.type as type22_11_0_ manuscript4_.manuscripts_id as manuscr11_11_5_, manuscript4_.id as id1_13_5_, manuscript4_.id as id1_13_1_, manuscript4_.file_address as file_add6_13_1_, manuscript4_.file_name as file_nam7_13_1_, manuscript4_.manuscripts_id as manuscr11_13_1_, manuscript4_.type as type9_13_1_, manuscript5_.manuscripts_id as manuscri7_11_6_, manuscript5_.id as id1_14_6_, manuscript5_.id as id1_14_2_, manuscript5_.department as departme2_14_2_, manuscript5_.department_name as departme3_14_2_, manuscript5_.editor_person as editor_p4_14_2_, manuscript5_.editor_person_name as editor_p5_14_2_, manuscript5_.manuscripts_id as manuscri7_14_2_, manuscript5_.quote_time as quote_ti6_14_2_ from manuscripts_att this_ inner join manuscripts manusc1_ on this_.manuscripts_id=manusc1_.id left outer join manuscripts_att manuscript4_ on manusc1_.id=manuscript4_.manuscripts_id left outer join manuscripts_quotes manuscript5_ on manusc1_.id=manuscript5_.manuscripts_id where this_.type=? order by this_.createtime desc
FetchMode.JOIN :會使用left join查詢 只產生一條sql語句 ,結果數據重複
@Fetch(FetchMode.SELECT) 後sql語句和結果(會產生N+1條sql語句)
Hibernate: select this_.id as id1_13_1_, this_.file_address as file_add6_13_1_, this_.file_name as file_nam7_13_1_, this_.manuscripts_id as manuscr11_13_1_, this_.type as type9_13_1_, manusc1_.id as id1_11_0_, manusc1_.content as content4_11_0_, manusc1_.create_time as create_t5_11_0_, manusc1_.title as title21_11_0_, manusc1_.type as type22_11_0_ from manuscripts_att this_ inner join manuscripts manusc1_ on this_.manuscripts_id=manusc1_.id where this_.type=? order by this_.createtime desc Hibernate: select manuscript0_.manuscripts_id as manuscri7_11_0_, manuscript0_.id as id1_14_0_, manuscript0_.id as id1_14_1_, manuscript0_.department as departme2_14_1_, manuscript0_.department_name as departme3_14_1_, manuscript0_.editor_person as editor_p4_14_1_, manuscript0_.editor_person_name as editor_p5_14_1_, manuscript0_.manuscripts_id as manuscri7_14_1_, manuscript0_.quote_time as quote_ti6_14_1_ from manuscripts_quotes manuscript0_ where manuscript0_.manuscripts_id=? Hibernate: select manuscript0_.manuscripts_id as manuscr11_11_0_, manuscript0_.id as id1_13_0_, manuscript0_.id as id1_13_1_, manuscript0_.createtime as createti2_13_1_, manuscript0_.create_person as create_p3_13_1_, manuscript0_.create_person_name as create_p4_13_1_, manuscript0_.download_count as download5_13_1_, manuscript0_.file_address as file_add6_13_1_, manuscript0_.file_name as file_nam7_13_1_, manuscript0_.file_suff as file_suf8_13_1_, manuscript0_.manuscripts_id as manuscr11_13_1_, manuscript0_.type as type9_13_1_, manuscript0_.view_count as view_co10_13_1_ from manuscripts_att manuscript0_ where manuscript0_.manuscripts_id=? .......................
@Fetch(FetchMode.SELECT) 會產生N+1條sql語句 ,結果正確,可是效率低
@Fetch(FetchMode.SUBSELECT) 產生兩條sql語句 第二條語句使用id in (…..)查詢出全部關聯的數據
Hibernate: select this_.id as id1_13_1_, this_.file_address as file_add6_13_1_, this_.file_name as file_nam7_13_1_, this_.manuscripts_id as manuscr11_13_1_, this_.type as type9_13_1_, manusc1_.id as id1_11_0_, manusc1_.content as content4_11_0_, manusc1_.create_time as create_t5_11_0_, manusc1_.title as title21_11_0_, manusc1_.type as type22_11_0_ from manuscripts_att this_ inner join manuscripts manusc1_ on this_.manuscripts_id=manusc1_.id where this_.type=? order by this_.createtime desc Hibernate: select manuscript0_.manuscripts_id as manuscri7_11_1_, manuscript0_.id as id1_14_1_, manuscript0_.id as id1_14_0_, manuscript0_.department as departme2_14_0_, manuscript0_.department_name as departme3_14_0_, manuscript0_.editor_person as editor_p4_14_0_, manuscript0_.editor_person_name as editor_p5_14_0_, manuscript0_.manuscripts_id as manuscri7_14_0_, manuscript0_.quote_time as quote_ti6_14_0_ from manuscripts_quotes manuscript0_ where manuscript0_.manuscripts_id in ( select manusc1_.id from manuscripts_att this_ inner join manuscripts manusc1_ on this_.manuscripts_id=manusc1_.id where this_.type=? )
FetchMode.SUBSELECT: 產生兩條sql語句 第二條語句使用id in (…..)查詢出全部關聯的數據 結果正確,效率相對高