在按列对desc排序时,与PostgreSQL DB一起使用的Hibernate会将空值设置为大于非空值。
SQL99标准提供了关键字“ NULLS LAST”来声明应将空值设置为低于非空值。
使用Hibernate的Criteria API是否可以实现“ NULLS LAST”行为?
鉴于HHH-465尚未修复,并且由于史蒂夫·埃伯索尔(Steve Ebersole)给出的原因而不会在近期内修复,因此,最好的选择CustomNullsFirstInterceptor是全局使用该问题的附件,也可以专门使用该附件来更改SQL语句。
CustomNullsFirstInterceptor
我在下面将其发布给读者(归功于Emilio Dolce):
public class CustomNullsFirstInterceptor extends EmptyInterceptor { private static final long serialVersionUID = -3156853534261313031L; private static final String ORDER_BY_TOKEN = "order by"; public String onPrepareStatement(String sql) { int orderByStart = sql.toLowerCase().indexOf(ORDER_BY_TOKEN); if (orderByStart == -1) { return super.onPrepareStatement(sql); } orderByStart += ORDER_BY_TOKEN.length() + 1; int orderByEnd = sql.indexOf(")", orderByStart); if (orderByEnd == -1) { orderByEnd = sql.indexOf(" UNION ", orderByStart); if (orderByEnd == -1) { orderByEnd = sql.length(); } } String orderByContent = sql.substring(orderByStart, orderByEnd); String[] orderByNames = orderByContent.split("\\,"); for (int i=0; i<orderByNames.length; i++) { if (orderByNames[i].trim().length() > 0) { if (orderByNames[i].trim().toLowerCase().endsWith("desc")) { orderByNames[i] += " NULLS LAST"; } else { orderByNames[i] += " NULLS FIRST"; } } } orderByContent = StringUtils.join(orderByNames, ","); sql = sql.substring(0, orderByStart) + orderByContent + sql.substring(orderByEnd); return super.onPrepareStatement(sql); } }