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

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

9 ответов


вот фрагмент 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());

с критериями 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;       
}

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


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

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

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

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


У меня есть ответ для языка запросов Hibernate для использования различных полей. Вы можете использовать *выбрать DISTINCT (TO_CITY) из FLIGHT_ROUTE*. Если вы используете SQL query, он возвращает список строк. Вы не можете использовать его возвращаемое значение по классу Entity. Таким образом, ответ на этот тип проблемы-use бумага 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 оператор запроса он получил отдельный ROUTE_ID и ввод в виде списка. И в запросе фильтруйте distinct TO_CITY из IN (список).

возвращаемый тип-это тип компонента сущности. Таким образом, вы можете это в AJAX, такие как AutoComplement.

может быть все в порядке


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

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

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