【问题标题】:How can someone give the HQL / SQL a better OO approach?有人如何为 HQL / SQL 提供更好的 OO 方法?
【发布时间】:2011-08-20 03:32:56
【问题描述】:

我使用 Hibernate 并且特别喜欢 Criteria api 来组合请求谓词,但在某些情况下无法使用它,因此我必须执行 HQL / SQL。

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

这里有人知道允许在 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;
    }

}

你怎么看这样的把戏?你知道支持的社区工具几乎可以做这种事情吗?

【问题讨论】:

    标签: java sql hibernate hql


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 谢谢会看jOOQ。我在这里阅读了 QueryDSL 允许的内容blog.springsource.com/2011/04/26/…
      • @Sebastien:这是一篇有趣的文章。我不知道现在春天也沿着 JPA 的道路前进。让我们看看这会导致什么
      • Lukas,Querydsl JPA查询序列化成JPQL/HQL,Querydsl SQL查询序列化成SQL
      • @Timo:好久不见! :-) 我不知道 HQL,我会立即更新我的答案!
      猜你喜欢
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多