Есть ли способ создать отдельный запрос в HQL. Либо с помощью ключевого слова «отличное», либо каким-либо другим методом. Я не уверен, является ли отличным ключевым словом HQL, но я ищу HQL-эквивалент ключевого слова SQL "отличный".
Как создать отдельный запрос в HQL
Ответы (11)
Вот фрагмент hql, который мы используем. (Имена изменены для защиты личности)
String queryString = "select distinct f from Foo f inner join foo.bars as b" +
" where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
Стоит отметить, что ключевое слово distinct в HQL не соответствует непосредственно ключевому слову distinct в SQL.
Если вы используете ключевое слово distinct в HQL, то иногда Hibernate будет использовать ключевое слово distinct SQL, но в некоторых ситуациях он будет использовать преобразователь результата для получения различных результатов. Например, когда вы используете внешнее соединение следующим образом:
select distinct o from Order o left join fetch o.lineItems
В этом случае невозможно отфильтровать дубликаты на уровне SQL, поэтому Hibernate использует ResultTransformer для фильтрации дубликатов после выполнения SQL-запроса.
сделай что-нибудь подобное в следующий раз
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
Вы также можете использовать Criteria.DISTINCT_ROOT_ENTITY с запросом Hibernate HQL.
Пример:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
У меня были некоторые проблемы с преобразователями результатов в сочетании с запросами HQL. Когда я пытался
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
это не сработало. Мне пришлось преобразовать вручную следующим образом:
final List found = trans.transformList(qry.list());
Преобразователи Criteria API работали просто отлично.
Мой основной запрос в модели выглядел так:
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
И я все еще не получал того, что считал «четкими» результатами. Они просто различались на основе комбинации первичных ключей в таблице.
Итак, в DaoImpl я добавил одно изменение строки и в итоге получил «отличный» результат, который хотел. Например, вместо того, чтобы видеть 00 четыре раза, я теперь вижу его только один раз. Вот код, который я добавил в DaoImpl:
@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {
Session session = (Session) entityManager.getDelegate();
org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
List<CacheModelBase> codes;
codes = q.list();
return codes;
}
Надеюсь, это помогло! Опять же, это может работать только в том случае, если вы следуете практикам кодирования, которые реализуют сервис, дао и тип проекта модели.
Предположим, у вас есть сущность клиента, сопоставленная с таблицей CUSTOMER_INFORMATION, и вы хотите получить список различных имен клиента. Вы можете использовать приведенный ниже фрагмент, чтобы получить то же самое.
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
Я надеюсь, что это помогает. Итак, здесь мы используем group by вместо отдельного ключевого слова.
Также ранее мне было трудно использовать отдельные ключевые слова, когда я хочу применить их к нескольким столбцам. Например, я хочу получить список различных имен firstName, lastName, а затем просто сгруппировать по ним. В этом случае мне было трудно использовать отличные.
Вы можете указать отдельное ключевое слово в своем построителе критериев, как это.
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));
И создайте конструктор поля в классе вашей модели.
У меня есть ответ для языка запросов Hibernate, чтобы использовать отдельные поля. Вы можете использовать *SELECT DISTINCT(TO_CITY) FROM FLIGHT_ROUTE*. Если вы используете запрос SQL, он возвращает список строк. Вы не можете использовать возвращаемое значение по классу сущностей. Таким образом, ответом для решения такого типа проблем является использование HQL с SQL.
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
Из оператора запроса SQL он получил DISTINCT ROUTE_ID и ввел его как список. И запрос IN отфильтровывает отдельный TO_CITY из IN (список).
Тип возвращаемого значения — тип Entity Bean. Таким образом, вы можете использовать AJAX, например AutoComplement.
Пусть все будет хорошо
Если вам нужно использовать ключевое слово new для пользовательского DTO в операторе select и нужны отдельные элементы, используйте new вне new, как показано ниже:
select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...
Вы можете просто добавить GROUP BY вместо Distinct
@Query(value = "from someTableEntity where entityCode in :entityCode" +
" group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);