2

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

それはすべて良いです。しかし、私の問題は、db 単体テストなどに HSQLDB を使用しているのに対し、デプロイには Oracle を使用していることです。stddev 関数はオラクルでは完全に機能しますが、HSQLDB にはありません。HSQLDB には stddev_pop と stddev_samp があります。それで、方言に基づいて別の機能を使用できる方法はありますか。

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

どんな助けでも大歓迎です。

ありがとう

4

2 に答える 2

1

方言を使用することは正しいアプローチです (ただし、テスト用と展開用に異なるデータベース エンジンを使用するのは少し難しいようです)。次のことができます。

  1. HSQL ダイアレクトを拡張し、適切な実装registerFunction()を登録するために使用します。stddev
  2. toSqlString()クラスのメソッドをオーバーライドし、 StdDevProjectionDialect レンダー関数名を設定します。

何かのようなもの:

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();
  }
于 2009-08-11T02:40:12.843 に答える
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 :)

于 2009-08-11T19:38:25.170 に答える