Hibernate/HQL для выполнения запроса SQL WHERE ... IN (SELECT...)
Как лучше всего использовать Hibernate для получения эквивалента следующего SQL-запроса, включающего подзапрос:
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; }
...
}
1 ответ
Когда я собирался опубликовать вопрос, я понял, что ответ - использовать 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();
}