У меня есть база данных Hibernate с одной таблицей, которая выглядит так:
PURCHASE_ID | PRODUCT_NAME | PURCHASE_DATE | PURCHASER_NAME | PRODUCT_CATEGORY
------------------------------------------------------------------------------
1 Notebook 09-07-2018 Bob Supplies
2 Notebook 09-06-2018 Bob Supplies
3 Pencil 09-06-2018 Bob Supplies
4 Tape 09-10-2018 Bob Supplies
5 Pencil 09-09-2018 Steve Supplies
6 Pencil 09-06-2018 Steve Supplies
7 Pencil 09-08-2018 Allen Supplies
И я хочу вернуть только самые новые покупки, основанные на некоторых других ограничениях. Например:
List<Purchase> getNewestPurchasesFor(Array<String> productNames, Array<String> purchaserNames) { ... }
Можно вызвать, используя:
List<Purchase> purchases = getNewestPurchasesFor(["Notebook", "Pencil"], ["Bob", "Steve"]);
На английском языке: "Дайте мне новейшие покупки, будь то ноутбук или карандаш, либо Бобом, либо Стивом".
И обеспечит:
PURCHASE_ID | PRODUCT_NAME | PURCHASE_DATE | PURCHASER_NAME
-----------------------------------------------------------
1 Notebook 09-07-2018 Bob
3 Pencil 09-06-2018 Bob
5 Pencil 09-09-2018 Steve
Таким образом, это похоже на "отдельный" поиск по нескольким столбцам или "лимит" на основе некоторого постсортированного уникального ключа с комбинированными столбцами, но все примеры, которые я нашел, показывают, используя SELECT DISTINCT(PRODUCT_NAME, PURCHASER_NAME)
чтобы получить эти только столбцы, тогда как мне нужно использовать формат:
from Purchases as entity where...
Чтобы типы моделей возвращались с неизменными отношениями.
В настоящее время мой запрос возвращает мне все старые покупки:
PURCHASE_ID | PRODUCT_NAME | PURCHASE_DATE | PURCHASER_NAME | PRODUCT_CATEGORY
------------------------------------------------------------------------------
1 Notebook 09-07-2018 Bob Supplies
2 Notebook 09-06-2018 Bob Supplies
3 Pencil 09-06-2018 Bob Supplies
5 Pencil 09-09-2018 Steve Supplies
6 Pencil 09-06-2018 Steve Supplies
Который, для повторных покупок, приводит к снижению производительности.
Существуют ли какие-либо специальные ключевые слова, которые я должен использовать для этого? Языки запросов и SQL-fu не мои сильные костюмы.
Редактировать:
Обратите внимание, что я в настоящее время использую API Criteria
и хотел бы продолжать это делать.
Criteria criteria = session.createCriteria(Purchase.class);
criteria.addOrder(Order.desc("purchaseDate"));
// Product names
Criterion purchaseNameCriterion = Restrictions.or(productNames.stream().map(name -> Restrictions.eq("productName", name)).toArray(Criterion[]::new));
// Purchaser
Criterion purchaserCriterion = Restrictions.or(purchaserNames.stream().map(name -> Restrictions.eq("purchaser", name)).toArray(Criterion[]::new));
// Bundle the two together
criteria.add(Restrictions.and(purchaseNameCriterion, purchaserCriterion));
criteria.list(); // Gives the above results
Если я попытаюсь использовать отдельную проекцию, я получаю сообщение об ошибке:
ProjectionList projections = Projections.projectionList();
projections.add(Projections.property("productName"));
projections.add(Projections.property("purchaser"));
criteria.setProjection(Projections.distinct(projections));
Результаты в:
17:08:39 ERROR Order by expression "THIS_.PURCHASE_DATE" must be in the result list in this case; SQL statement:
Поскольку, как упоминалось выше, добавление проекционного/различного набора столбцов указывает на Hibernate, что я хочу, чтобы эти столбцы были как результат/возвращаемое значение, когда я хочу просто ограничить возвращаемые объекты модели на основе уникальных значений столбца.