寻找HQL构建器(Hibernate查询语言)

Séb*_*rra 7 java hibernate hql

我正在寻找Java中的HQL构建器.我想摆脱像这样的事情:

StringBuilder builder = new StringBuilder()
    .append("select stock from ")
    .append( Stock.class.getName() )
    .append( " as stock where stock.id = ")
    .append( id );
Run Code Online (Sandbox Code Playgroud)

我宁愿有类似的东西:

HqlBuilder builder = new HqlBuilder()
    .select( "stock" )
    .from( Stock.class.getName() ).as( "stock" )
    .where( "stock.id" ).equals( id );
Run Code Online (Sandbox Code Playgroud)

我google了一下,我找不到一个.

我写了一个快速和愚蠢的东西HqlBuilder,适合我现在的需求,但我很想找到一个比我更多的用户和测试.

注意:我希望能够做到这样的事情以及更多,我没有使用Criteria API:

select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.someValue = bonus.id
Run Code Online (Sandbox Code Playgroud)

即.从Bonus表中选择所有属性someValue指向任何奖金的股票.

谢谢!

Tim*_*per 7

对于您的问题的类型安全方法,请考虑Querydsl.

示例查询变为

HQLQuery query = new HibernateQuery(session);
List<Stock> s = query.from(stock, bonus)
  .where(stock.someValue.eq(bonus.id))
  .list(stock);
Run Code Online (Sandbox Code Playgroud)

Querydsl使用APT代码生成,如JPA2,并支持JPA/Hibernate,JDO,SQL和Java集合.

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


sbl*_*ndy 6

未在标准API为你做?它看起来几乎就像你要求的那样.


sbl*_*ndy 5

@ Sébastien Rocca-Serra
现在我们正在某个地方具体。您尝试进行的那种连接实际上无法通过 Criteria API 实现,但是子查询应该可以完成相同的事情。首先DetachedCriteria为奖金表创建 a ,然后为 使用IN运算符someValue

DetachedCriteria bonuses = DetachedCriteria.forClass(Bonus.class);
List stocks = session.createCriteria(Stock.class)
    .add(Property.forName("someValue").in(bonuses)).list();
Run Code Online (Sandbox Code Playgroud)

这相当于

select stock
from com.something.Stock as stock
where stock.someValue in (select bonus.id from com.something.Bonus as bonus)
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是如果您引用了不同的表,someValue并且您的 ID 在所有表中都不是唯一的。但是您的查询会遇到同样的缺陷。


ebe*_*ger 5

对于另一个类型安全的查询dsl,我推荐http://www.torpedoquery.org.该库仍然很年轻,但它通过直接使用您的实体类提供类型安全.这意味着在重构或重新设计之前查询不再适用时,早期的编译器错误.

我还为你提供了一个例子.我想从你的帖子中你试图做一个子查询限制,所以我根据这个例子:

import static org.torpedoquery.jpa.Torpedo.*;

Bonus bonus = from(Bonus.class);
Query subQuery = select(bonus.getId());

Stock stock = from(Stock.class);
where(stock.getSomeValue()).in(subQuery);

List<Stock> stocks = select(stock).list(entityManager);
Run Code Online (Sandbox Code Playgroud)