Как создать отдельный запрос в HQL

Есть ли способ создать отдельный запрос в HQL. Либо с помощью ключевого слова «отличное», либо каким-либо другим методом. Я не уверен, является ли отличным ключевым словом HQL, но я ищу HQL-эквивалент ключевого слова SQL "отличный".


person Mike Pone    schedule 04.11.2008    source источник
comment
Проекция? stackoverflow.com/questions/25536868 /   -  person rogerdpack    schedule 07.05.2021


Ответы (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});
person Feet    schedule 04.11.2008
comment
Я когда-либо использовал спящий режим только с MySQL - не знаю, как справиться с проблемой mssql. - person Feet; 14.05.2012
comment
Функция getHibernateTemplate() принадлежит Spring Framework, а не стандартному API. Знаете ли вы эквивалент без использования Spring Framework? - person Matthieu.V; 11.09.2020

Стоит отметить, что ключевое слово distinct в HQL не соответствует непосредственно ключевому слову distinct в SQL.

Если вы используете ключевое слово distinct в HQL, то иногда Hibernate будет использовать ключевое слово distinct SQL, но в некоторых ситуациях он будет использовать преобразователь результата для получения различных результатов. Например, когда вы используете внешнее соединение следующим образом:

select distinct o from Order o left join fetch o.lineItems

В этом случае невозможно отфильтровать дубликаты на уровне SQL, поэтому Hibernate использует ResultTransformer для фильтрации дубликатов после выполнения SQL-запроса.

person Daniel Alexiuc    schedule 23.11.2008
comment
Ответил здесь: stackoverflow.com/questions/5471819/ - person Daniel Alexiuc; 31.03.2011

сделай что-нибудь подобное в следующий раз

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();
person Michael    schedule 19.05.2011
comment
Это неоптимально: вместо того, чтобы отбрасывать повторения на уровне базы данных, он просто вытягивает данные из базы данных в память с повторениями и всем остальным, а затем отбрасывает повторения; в зависимости от того, как часто данные повторяются, это может значительно увеличить количество операций ввода-вывода. - person Haroldo_OK; 21.01.2019

Вы также можете использовать Criteria.DISTINCT_ROOT_ENTITY с запросом Hibernate HQL.

Пример:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
person aadi53    schedule 14.08.2014
comment
Это неоптимально: вместо того, чтобы отбрасывать повторения на уровне базы данных, он просто вытягивает данные из базы данных в память с повторениями и всем остальным, а затем отбрасывает повторения; в зависимости от того, как часто данные повторяются, это может значительно увеличить количество операций ввода-вывода. - person Haroldo_OK; 21.01.2019

У меня были некоторые проблемы с преобразователями результатов в сочетании с запросами HQL. Когда я пытался

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

это не сработало. Мне пришлось преобразовать вручную следующим образом:

final List found = trans.transformList(qry.list());

Преобразователи Criteria API работали просто отлично.

person Tadeusz Kopec    schedule 28.05.2009
comment
чтобы получить 10к (: - person timmz; 03.01.2018

Мой основной запрос в модели выглядел так:

@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;       
}

Надеюсь, это помогло! Опять же, это может работать только в том случае, если вы следуете практикам кодирования, которые реализуют сервис, дао и тип проекта модели.

person Nathan Mitchell    schedule 03.11.2014

Предположим, у вас есть сущность клиента, сопоставленная с таблицей CUSTOMER_INFORMATION, и вы хотите получить список различных имен клиента. Вы можете использовать приведенный ниже фрагмент, чтобы получить то же самое.

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

Я надеюсь, что это помогает. Итак, здесь мы используем group by вместо отдельного ключевого слова.

Также ранее мне было трудно использовать отдельные ключевые слова, когда я хочу применить их к нескольким столбцам. Например, я хочу получить список различных имен firstName, lastName, а затем просто сгруппировать по ним. В этом случае мне было трудно использовать отличные.

person chammu    schedule 12.05.2015

Вы можете указать отдельное ключевое слово в своем построителе критериев, как это.

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));

И создайте конструктор поля в классе вашей модели.

person Santosh Singh    schedule 21.08.2018

У меня есть ответ для языка запросов 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.

Пусть все будет хорошо

person San Lin Naing    schedule 22.02.2013

Если вам нужно использовать ключевое слово new для пользовательского DTO в операторе select и нужны отдельные элементы, используйте new вне new, как показано ниже:

select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...
person Manish Sharma    schedule 11.05.2020

Вы можете просто добавить GROUP BY вместо Distinct

@Query(value = "from someTableEntity where entityCode in :entityCode" +
            " group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);
person Rustem    schedule 27.05.2020