【问题标题】:Hibernate Computed Criteria OrderHibernate 计算标准顺序
【发布时间】:2011-01-14 14:58:55
【问题描述】:

我有一个存储各种语言特定字符串的 Oracle XMLType 列。我需要构建一个在此列上排序的 Hibernate 标准。为此,我需要使用 Oracle 函数提取值。这个标准是由我编写的代码自动生成的,但我一辈子都无法弄清楚如何通过标准 API 提取价值并对其进行排序。基本上,生成的 SQL 应该类似于:

SELECT EXTRACTVALUE(title, '//value[@lang="EN"]') AS enTitle
FROM domain_object 
ORDER BY enTitle

我暂时摆弄了一些预测,但它们似乎执行了第二次选择。我认为这会导致休眠选择所有值并在内存中根据投影对它们进行排序?这将是非常不可取的=\

【问题讨论】:

    标签: oracle hibernate sorting criteria xmltype


    【解决方案1】:

    另一个通用解决方案是 NativeSQLOrder,请参阅http://opensource.atlassian.com/projects/hibernate/browse/HHH-2381。我不明白,为什么 Hibernate 还没有这个功能。

    【讨论】:

      【解决方案2】:

      好的,我找到了一个解决方案。不确定这是最好的,所以如果有人想提供更好的答案/改进我的解决方案,我会暂时打开它。

      我所做的就是扩展org.hibernate.criterion.Order

      package com.mycorp.common.hibernate;
      
      import org.hibernate.Criteria;
      import org.hibernate.HibernateException;
      import org.hibernate.criterion.CriteriaQuery;
      import org.hibernate.criterion.Order;
      import org.hibernate.engine.SessionFactoryImplementor;
      
      import com.mycorp.LocalizationUtil;
      
      public class LocalStringOrder extends Order {
          private static final long serialVersionUID = 1L;
      
          private boolean ascending;
          private String  propName;
      
          public LocalStringOrder(String prop, boolean asc) {
              super(prop, asc);
              ascending    = asc;
              propName = prop;
          }
      
          public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
              String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propName);
              StringBuffer fragment = new StringBuffer();
              for ( int i=0; i<columns.length; i++ ) {
                  SessionFactoryImplementor factory = criteriaQuery.getFactory();
                  fragment.append( factory.getDialect().getLowercaseFunction() )
                  .append('(');
                  fragment.append("EXTRACTVALUE(");
                  fragment.append( columns[i] );
                  fragment.append(", '//value[@lang=\"" + 
                      LocalizationUtil.getPreferedLanguage().name() + 
                      "\"')");
                  fragment.append(')');
                  fragment.append( ascending ? " asc" : " desc" );
                  if ( i<columns.length-1 ) fragment.append(", ");
              }
              return fragment.toString();
          }
      
          public static Order asc(String propertyName) {
              return new LocalStringOrder(propertyName, true);
          }
      
      
          public static Order desc(String propertyName) {
              return new LocalStringOrder(propertyName, false);
          }
      }
      

      然后只需说criteria.addOrder(LocalStringOrder.asc('prop'))

      【讨论】:

      • +1 这对我来说看起来不错。希望我能替你想到!我想到的另一件事是创建一个视图并查询它,这对某些人来说可能更清楚。但我更喜欢你的解决方案。
      猜你喜欢
      • 2013-12-07
      • 2020-02-12
      • 1970-01-01
      • 1970-01-01
      • 2016-04-14
      • 2020-04-15
      • 2013-11-25
      • 1970-01-01
      • 2014-01-30
      相关资源
      最近更新 更多