hibernate 一對多 取多方數據重複問題,FetchMode.JOIN、FetchMode.SELECT、FetchMode.SUBSELECT區別

問題描述:稿件附件表數據時出現多條重複數據。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 (…..)查詢出全部關聯的數據 結果正確,效率相對高

相關文章
相關標籤/搜索