2009-08-11 2 views
2

基準APIを使用してImを構築するクエリで標準偏差プロジェクションを使用したいと考えています。私は単にこのHibernateの基準で異なる射影関数を使用するDialectに基づくAPI

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)); 

ザッツすべて。しかし、私の問題は、私がデプロイするためにOracleを使用するのに対し、私はすべてのdbユニットテストなどでHSQLDBを使用することです。 stddev関数はOracleでは完全に機能しますが、HSQLDBには存在しません。 HSQLDBにはstddev_popとstddev_sampがあります。ですから、私は方言に基づいて別の関数を使用することができます。

"stddev"を適切なHSQL関数に登録するためにHSQL方言を拡張できますが、Criteria APIを使用して構築されたクエリでhsql関数を使用する方法がわかりません。

どのようなヘルプもgretです。 (私は展開の対テストのために別のデータベースエンジンを使用すると、少しあやふやなようだと言っているんだが)方言を使う

おかげで

答えて

1

正しいアプローチです。あなたは、次の操作を行うことができます。

  1. はHSQLの方言を拡張し、適切なstddev実装を登録するregisterFunction()を使用しています。
  2. あなたのStdDevProjectionクラスにtoSqlString()メソッドをオーバーライドし、Dialect render function nameを持っています。

のような何か:

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のように見えるものです:)