2012-12-19 48 views
0

什麼是使用Hibernate來實現,涉及的子查詢下面的SQL查詢的等效的最佳方式:的Hibernate/HQL實現SQL WHERE ... IN(SELECT ...)查詢

SELECT cat.description, cat.code FROM 
    THING_CATEGORY cat 
WHERE cat.code IN (
    SELECT thing.CATEGORY_CODE FROM THING thing 
    WHERE thing.COUNTRY_CODE IN ('AU', 'US', 'UK') 
) 

這是可能最好的辦法是直接把它傳給是SQL(PL/SQL)我的數據庫的味道本身所做的數據庫,但我還沒有真正能夠弄清楚它是如何在一個Hibernate Criterion對象來完成,所以我專門想知道這一點。

請注意:THING表是絕對巨大的,有很多列,所以我不想從數據庫中拉下所有的THING實體來實現這個邏輯,因爲它不會被執行。限制THING_CATEGORY結果的邏輯必須在數據庫內完成,並在其中進行優化。實際上,當我用原始PL/SQL進行查詢時,幾乎需要一整秒才能得到結果。

爲了給實體的想法(注意THING_CATEGORY沒有回THING參考):

@Entity @Table(name = "THING") 
public class Thing 
{ 
    private String categoryCode; 
    @Column(name = "CATEGORY_CODE", nullable = false, length = 3) 
    public String getCategoryCode() { return this.categoryCode; } 

    private String countryCode; 
    @Column(name = "COUNTRY_CODE", nullable = false, length = 2) 
    public String getCountryCode() { return this.countryCode; } 

    ... 
} 

@Entity @Table(name = "THING_CATEGORY") 
public class ThingCategory 
{ 
    private String code; 
    @Id @Column(name = "CODE", unique = true, nullable = false, length = 3) 
    public String getCode() { return this.code; } 

    ... 
} 

回答

0

當我正要張貼我意識到答案的問題是使用Hibernate DetachedCriteria包含THING限制子查詢。然後將其添加到THING_CATEGORY主要查詢的標準中。

所以Hibernate的代碼如下所示:

public List<ThingCategory> getRestrictedByCountrySet(List<String> countryCodes) 
{ 
    Criterion thingCriterion = Restrictions.in("countryCode", countryCodes); 
    DetachedCriteria thingSubQuery = DetachedCriteria.forClass(Thing.class) 
    .add(thingCriterion) 
    .setProjection(Projections.property("categoryCode"); 

    Criteria thingCategoryCriteria = getHbSession().createCriteria(ThingCategory.class) 
    .add(Property.forName("code").in(thingSubQuery)); 

    return thingCategoryCriteria.list(); 
}