休眠实体查询,用于在单个表中查找最新的半唯一行
我有一个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表明我希望这些列作为结果/返回值,而我想要的只是基于唯一列值来限制返回的模型对象。