2009-08-11 1 views
2

Я хочу использовать проекцию стандартного отклонения в запросе, который Im создает с использованием API критериев. Я могу сделать что-то просто, как этотИспользование различных проекционных функций в критериях Hibernate API, основанных на Dialect

public class StdDevProjection extends AggregateProjection { 

    public StdDevProjection(String propertyName) { 
     super("stddev", propertyName); 
    } 

    public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
    throws HibernateException { 
     return new Type[] { Hibernate.DOUBLE }; 
    } 

}

, а затем я могу использовать его с моими критериями, как:

myCriteriea.setProjection(new StdDevProjection(myproperty)); 

Это все хорошо. Но моя проблема заключается в том, что я использую HSQLDB для любых тестов модулей db и т. Д., Тогда как мы используем Oracle для развертывания. Функция stddev отлично работает в оракуле, но ее нет в HSQLDB. HSQLDB имеет stddev_pop и stddev_samp. Так что я могу использовать другую функцию, основанную на диалекте.

Возможно, я могу расширить диалоги HSQL, чтобы зарегистрировать «stddev» в соответствующей функции HSQL, но затем я не уверен, как использовать функцию hsql в запросе, построенном с использованием API критериев.

Любая помощь может быть решена.

Благодаря

ответ

1

Использование диалекте правильный подход (хотя я должен сказать, что с помощью различных двигателей базы данных для тестирования против развертывания кажется немного сомнительный). Вы можете сделать следующее:

  1. Продлить HSQL диалекте и использовать registerFunction() зарегистрировать соответствующий stddev реализации.
  2. Переопределить метод toSqlString() в вашем классе StdDevProjection и иметь имя функции отображения диалекта.

Что-то вроде:

public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException { 
    Dialect dialect = criteriaQuery.getFactory().getDialect(); 
    SQLFunction function = (SQLFunction) dialect.getFunctions().get(this.aggregate); 
    //TODO: throw an exception if function is not registered 

    //create function argument array 
    List functionArgs = new ArrayList(1); 
    functionArgs.add(criteriaQuery.getColumn(criteria, propertyName)); 

    return new StringBuffer() 
    .append(function.render(functionArgs, criteriaQuery.getFactory())) 
    .append(" as y").append(loc).append('_') 
    .toString(); 
    } 
0
public class StdDevProjection extends AggregateProjection { 
/** 
* 
*/ 
    private static final long serialVersionUID = -7056189336427534748L; 
    private String aggregateName = null; 
    public StdDevProjection(String propertyName) { 
     super("stddev", propertyName); 
     this.aggregateName = "stddev"; 
    } 
    @Override 
    public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
    throws HibernateException { 
     return new Type[] { Hibernate.DOUBLE }; 
    } 
    @Override 
    public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) 
      throws HibernateException { 
     Dialect dialect = criteriaQuery.getFactory().getDialect(); 
     SQLFunction function = (SQLFunction)dialect.getFunctions().get(this.aggregateName); 
     if(function == null) { 
      throw new HibernateException("Couldnt find function for aggregate: " + aggregateName + " in Dialect: " + dialect); 
     } 
    //create function argument array 
     List functionArgs = new ArrayList(1); 
     functionArgs.add(criteriaQuery.getColumn(criteria, propertyName)); 

     return new StringBuffer() 
      .append(function.render(functionArgs, criteriaQuery.getFactory())) 
      .append(" as y").append(loc).append('_') 
      .toString(); 


    } 


} 

и это то, что диалект выглядит

public class ExtendedHSQLDialect extends HSQLDialect { 
    public ExtendedHSQLDialect() { 
     super(); 
     registerFunction("stddev", new StandardSQLFunction("stddev_pop",Hibernate.DOUBLE)); 
     } 
} 

Спасибо ChssPly76 :)

 Смежные вопросы

  • Нет связанных вопросов^_^