如何为HQL / SQL提供更好的OO方法?

时间:2011-05-06 12:03:42

标签: java sql hibernate hql

我使用Hibernate,特别是像Criteria api一样编写请求谓词,但在某些情况下,它不可能使用它,所以我必须做HQL / SQL。

我不喜欢使用HQL / SQL查询构建主要是因为除了不是OO之外,很难像使用Criteria那样使用谓词进行组合。 我不喜欢构建完整查询String的方法,构建该查询,然后添加所有查询参数。

这里有人知道允许在Hibernate / JPA中简化HQL / SQL查询的编写和可重用性的工具吗?

实际上我已经创建了一个允许我同时构建查询部分和参数部分的小类。我想它可能不会响应任何人的情况但它仍然可以很好地用于我的简单用例:我主要在where子句中用AND和OR组成谓词组合。

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

/**
 * This permits to append to query step by step and give a better lisibility to some queries
 * Works with hql and sql
 * 
 * @author Sebastien Lorber (<i>lorber.sebastien@gmail.com</i>)
 */
public class AppendableQuery  {

    private Map<String,Object> parameters;
    private Map<String,Collection<? extends Object>> parametersLists;
    private StringBuilder queryBuilder;

    /**
     * Creates a new empty query
     */
    public AppendableQuery() {
        parameters = new HashMap<String, Object>();
        parametersLists = new HashMap<String, Collection<? extends Object>>();
        queryBuilder = new StringBuilder();
    }

    /**
     * Append to the query
     * @param querySubstring
     */
    public AppendableQuery append(String querySubstring) {
        queryBuilder.append(querySubstring);
        return this;
    }

    /**
     * Set a parameter to the query
     * @param paramKey
     * @param paramValue
     */
    public AppendableQuery setParameter(String paramKey,Object paramValue) {
        parameters.put(paramKey, paramValue);
        return this;
    }

    /**
     * Set a parameter list to the query
     * @param paramKey
     * @param paramValue
     * @return
     */
    public AppendableQuery setParameterList(String paramKey,Collection<? extends Object> paramValue) {
        parametersLists.put(paramKey, paramValue);
        return this;
    }

    /**
     * Gets an HQL query based on what you filled
     * @param hibernateSession
     * @return SQL query
     */
    public Query getHQLQuery(Session hibernateSession) {
        Query query = hibernateSession.createQuery(queryBuilder.toString());
        for ( Map.Entry<String, Object> entry : parameters.entrySet() ) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        for ( Map.Entry<String, Collection<? extends Object>> entry : parametersLists.entrySet() ) {
            query.setParameterList(entry.getKey(), entry.getValue());
        }
        return query;
    }

    /**
     * Gets an SQL query based on what you filled
     * @param hibernateSession
     * @return SQL query
     */
    public SQLQuery getSQLQuery(Session hibernateSession) {
        SQLQuery query = hibernateSession.createSQLQuery(queryBuilder.toString());
        for ( Map.Entry<String, Object> entry : parameters.entrySet() ) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        for ( Map.Entry<String, Collection<? extends Object>> entry : parametersLists.entrySet() ) {
            query.setParameterList(entry.getKey(), entry.getValue());
        }
        return query;
    }

}

你怎么看待这样的伎俩?您是否了解支持的社区工具几乎可以做这类事情?

2 个答案:

答案 0 :(得分:1)

我认为QueryDSL有一些SQL / JPQL / HQL与JPA集成的方法。

如果不是必须使用Hibernate / JPA,您可能需要查看我编写的Java数据库抽象框架jOOQ。它支持几乎所有标准和非标准SQL结构,同时仍然是面向对象的。

答案 1 :(得分:1)

对于更多OO风格的构造,您可能需要考虑使用LiquidformQuerydsl。 Liquidform是一个更轻量级的工具,不需要代码生成,Querydsl的开销略高,但语法更易读,更紧凑。我也相信Querydsl的表现力更高。

不需要推出自己的JPQL构建器,已有经过验证的解决方案。

由于我是Querydsl的维护者,这个答案是有偏见的。