[英]JPA Criteria Query API and order by null last
我的問題是空值必須是按語句的最后順序。 我的代碼片段如下。 我使用javax持久性條件構建器。 我的查詢很復雜。
import javax.persistence.criteria.CriteriaBuilder;
public Predicate getSomePredicate() {
Predicate predicate = cb.conjunction();....
...predicate.getExpressions().add(cb.and(cb.or(cb.and(v1, v2), cb.and(s1, s2))));
EOrderByType orderType = EOrderByType.values()[orderBy]
;
switch (orderType) {
case PRICE: cq.where(predicate).orderBy(cb.asc(root.get("price")));
break;
case PRICE_HIGH_TO_LOW: cq.where(predicate).orderBy(cb.desc(root.get("price")));
break;
case CONSUPTION: cq.where(predicate).orderBy(cb.desc(root.get("consume")));
break;
default:
break;
}
return cq.getRestriction();
}
如何使用條件生成器按價格為空的順序實現訂單?
嗨,我幾乎搜索了所有互聯網頁面,然后找到了解決方案,您可以按部分編寫開關案例的順序。 如下所示:如果price為空,則按desc排序,價格值為1000000,如果price為空,則按asc排序,價格值為0。如果需要這些,則可以編寫如下表達式。
EOrderByType orderType = EOrderByType.values()[orderBy];
Expression<Object> queryCase = cb.selectCase().when(cb.isNull(root.get("price")), 100000000).otherwise(root.get("price"));
Direction dir = Direction.ASC;
switch (orderType) {
case UCUZDAN_PAHALIYA:
queryCase = cb.selectCase().when(cb.isNull(root.get("price")), 100000000).otherwise(root.get("price"));
break;
case PAHALIDAN_UCUZA:
queryCase = cb.selectCase().when(cb.isNull(root.get("price")), 0).otherwise(root.get("price"));
dir = Direction.DESC;
break;
}
cq.where(predicate).orderBy(direction( cb, queryCase, dir));
這是katsu對自己問題的回答的擴展。 我試圖找到一種解決方案,能夠對表的大多數列進行排序,其中某些列允許具有空值。 我想按升序排序時,將空值放在最低的非空值前面,而當按降序排序時,要在最低的非空值之后。 換句話說,這與(Oracle的)默認行為截然相反。
我找到了其他方法可以做到這一點,但是這種方法不需要我脫離Hibernate和JPA 2持久性,但仍然可以獲得我想要的結果。 這是摘錄自我的實際代碼的一小段代碼,但合並在一個位置,並且更改了一些名稱。 您看到的任何語法,編譯類型錯誤都可能是由於該原因。
// sortByColumn is a String containing the Hibernate version of the column name, which had
// been assigned as the ID of the table header column of the column by which we are sorting.
// sortAscending is a Boolean object containing Boolean.TRUE if we are to sort in ascending
// order or Boolean.FALSE or null if we are to sort in descending order. This may seem a
// bit odd, but in the case we need this for, the default sort column is a release date and
// reverse chronological order is the most useful in that case.
// Also defined are: CriteriaQuery<SoftwareVersion> criteriaQuery and
// CriteriaBuilder criteriaBuilder by the typical means.
final Root<SoftwareVersion> softwareVersionRoot =
criteriaQuery.from(SoftwareVersion.class);
private static final String EMPTY_STRING = "";
if (sortByColumn != null && sortByColumn.trim().length() > 0) {
Order sortOrder;
Expression<String> sortColumnExpression;
if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileLength.getName()) ||
sortByColumn.equalsIgnoreCase(SoftwareVersion_.releaseTimestamp.getName())) {
// The two non-String fields (exposed to the user) that we don't need to have the
// lower() function operate upon.
sortColumnExpression = oemSoftwareVersionRoot.get(sortByColumn);
} else {
// We use the lower() function to enforce case insensitive sorting on the columns we
// show to the user, which are all Strings except as noted above.
Expression<String> rootExpression = oemSoftwareVersionRoot.get(sortByColumn);
sortColumnExpression = criteriaBuilder.lower(rootExpression);
}
// The columns for installation file name, installation file length and release timestamp
// are just three of the columns that we allow the user to sort by. However, these three
// may have null values in the database, and require some special handling.
if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileLength.getName()) ||
sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileName.getName()) ||
sortByColumn.equalsIgnoreCase(SoftwareVersion_.releaseTimestamp.getName())
) {
Expression<Object> queryCase;
if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileName.getName())) {
// Installation file name is a (case insensitive) String
queryCase = criteriaBuilder.selectCase().when(
criteriaBuilder.isNull(sortColumnExpression),
StringUtil.EMPTY_STRING).otherwise(sortColumnExpression);
} else if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.releaseTimestamp.getName())) {
// Release timestamp is a database timestamp
LocalDateTime dateTime = LocalDateTime.of(1970,1,1,0,0);
// Equivalent to Unix epoch time. Note month is 1-12, not 0-11
queryCase = criteriaBuilder.selectCase().when(
criteriaBuilder.isNull(sortColumnExpression),
Timestamp.valueOf(dateTime)).otherwise(sortColumnExpression);
} else {
// Installation file length is a Long (or BigDecimal) computed when the file is uploaded.
// The user can't set or change it, but can sort by it.
queryCase = criteriaBuilder.selectCase().when(
criteriaBuilder.isNull(sortColumnExpression),
Long.valueOf(0)).otherwise(sortColumnExpression);
}
if (asc != null && asc.booleanValue()) {
sortOrder = criteriaBuilder.asc(queryCase);
} else {
sortOrder = criteriaBuilder.desc(queryCase);
}
} else {
if (asc != null && asc.booleanValue()) {
sortOrder = criteriaBuilder.asc(sortColumnExpression);
} else {
sortOrder = criteriaBuilder.desc(sortColumnExpression);
}
}
criteriaQuery.orderBy(sortOrder);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.