2011-05-06 43 views
4

我使用Hibernate,尤其是像Criteria api一样使用请求谓词进行组合,但是在某些情况下,不可能使用它,所以我必须执行HQL/SQL。某人如何为HQL/SQL提供更好的面向对象方法?

我不喜欢用HQL/SQL查询构建主要是因为,除了不是面向对象之外,很难用谓词来构造,就像我们可以使用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>[email protected]</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; 
    } 

} 

你觉得这样的把戏呢?你知道支持的社区工具几乎可以做这种事吗?

回答

1

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

推出自己的JPQL构建器是没有必要的,现在已经有成熟的解决方案。

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

1

我认为QueryDSL有一些SQL/JPQL/HQL与JPA的整合手段。

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

+1

谢谢你会看jOOQ。我已阅读QueryQuery允许在这里http://blog.springsource.com/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/ – 2011-05-06 13:04:39

+0

@Sebastien:这是一篇有趣的文章。现在,我不知道春天也在JPA的道路上。让我们来看看导致 – 2011-05-06 13:54:16

+0

Lukas,Querydsl JPA查询被序列化为JPQL/HQL,Querydsl SQL查询被序列化为SQL – 2011-05-07 14:15:48