我正在寻找Java中HQL的构建器。我想摆脱像:
这样的事情StringBuilder builder = new StringBuilder()
.append("select stock from ")
.append( Stock.class.getName() )
.append( " as stock where stock.id = ")
.append( id );
我宁愿有类似的东西:
HqlBuilder builder = new HqlBuilder()
.select( "stock" )
.from( Stock.class.getName() ).as( "stock" )
.where( "stock.id" ).equals( id );
我用Google搜索了一下,我找不到一个。
我写了一个快速&笨HqlBuilder
现在适合我的需要,但我很想找到一个比我单独拥有更多用户和测试的人。
注意:我希望能够做到这样的事情以及更多,我没有使用Criteria API:
select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.someValue = bonus.id
即。从奖金表中选择财产someValue
指向任何奖金的所有股票。
谢谢!
答案 0 :(得分:6)
Criteria API不是为你做的吗?它看起来几乎就像你要求的那样。
答案 1 :(得分:6)
对于问题的类型安全方法,请考虑Querydsl。
示例查询变为
HQLQuery query = new HibernateQuery(session);
List<Stock> s = query.from(stock, bonus)
.where(stock.someValue.eq(bonus.id))
.list(stock);
Querydsl使用APT代码生成,如JPA2,并支持JPA / Hibernate,JDO,SQL和Java集合。
我是Querydsl的维护者,所以这个答案有偏见。
答案 2 :(得分: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);
答案 3 :(得分:4)
看起来您想要使用Hibernate内置的Criteria查询API。要执行上述查询,它将如下所示:
List<Stock> stocks = session.createCriteria(Stock.class)
.add(Property.forName("id").eq(id))
.list();
如果您还没有访问Hibernate会话,可以像这样使用'DetachedCriteria':
DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class)
.add(Property.forName("id").eq(id));
如果您希望获得具有特定ID的奖金的所有股票,您可以执行以下操作:
DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class)
.createCriteria("Stock")
.add(Property.forName("id").eq(id)));
要获得更多信息,请查看Hibernate文档中的Criteria Queries
答案 4 :(得分:4)
@ Sébastien Rocca-Serra
现在我们正在变得具体。您尝试做的联接实际上并不是通过Criteria API实现的,但是子查询应该完成同样的事情。首先,为奖励表创建DetachedCriteria
,然后使用IN
运算符someValue
。
DetachedCriteria bonuses = DetachedCriteria.forClass(Bonus.class);
List stocks = session.createCriteria(Stock.class)
.add(Property.forName("someValue").in(bonuses)).list();
这相当于
select stock
from com.something.Stock as stock
where stock.someValue in (select bonus.id from com.something.Bonus as bonus)
唯一的缺点是,如果您在someValue
中引用了不同的表,并且您的ID在所有表中都不是唯一的。但是你的查询会遇到同样的缺陷。
答案 5 :(得分:2)
select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.bonus.id = bonus.id
那只是一个加入。 Hibernate会自动执行此操作,当且仅当您在Stock
和Bonus
设置之间建立映射并且bonus
是Stock
的属性时才会自动执行此操作。 Criteria.list()
将返回Stock
个对象,您只需致电stock.getBonus()
。
注意,如果你想做任何事情,比如
select stock
from com.something.Stock as stock
where stock.bonus.value > 1000000
您需要使用Criteria.createAlias()
。它就像
session.createCriteria(Stock.class).createAlias("bonus", "b")
.add(Restrictions.gt("b.value", 1000000)).list()
答案 6 :(得分:2)
Criteria API不提供HQL中可用的所有功能。例如,您不能在同一列上执行多个连接。
为什么不使用 NAMED QUERIES ?看起来更干净:
Person person = session.getNamedQuery("Person.findByName")
.setString(0, "Marcio")
.list();
答案 7 :(得分:2)
我为OMERO编写了一个GPL解决方案,您可以根据自己的情况轻松构建该解决方案。
用法:
QueryBuilder qb = new QueryBuilder();
qb.select("img");
qb.from("Image", "img");
qb.join("img.pixels", "pix", true, false);
// Can't join anymore after this
qb.where(); // First
qb.append("(");
qb.and("pt.details.creationTime > :time");
qb.param("time", new Date());
qb.append(")");
qb.and("img.id in (:ids)");
qb.paramList("ids", new HashSet());
qb.order("img.id", true);
qb.order("this.details.creationEvent.time", false);
它用作状态机“select-&gt; from-&gt; join-&gt; where-&gt; order”等,并与可选参数保持同步。 Criteria API无法执行多个查询(请参阅HHH-879),因此最后编写此小类以包装StringBuilder更简单。 (注意:有一个票据HHH-2407描述了一个Hibernate分支,它应该统一两者。之后,重新访问Criteria API可能是有意义的)
答案 8 :(得分:2)
查看hibernate-generic-dao项目提供的搜索包。这是一个相当不错的HQL Builder实现。
答案 9 :(得分:2)
我知道这个帖子很老了,但我也在寻找一个HqlBuilder而且我找到了这个"screensaver" project
它不是Windows屏幕保护程序,它是一个
“实验室信息管理系统(LIMS),用于执行小分子和RNAi筛选的高通量筛选(HTS)设施。”
它包含一个看起来非常好的HQLBuilder。
以下是可用方法的示例列表:
...
HqlBuilder select(String alias);
HqlBuilder select(String alias, String property);
HqlBuilder from(Class<?> entityClass, String alias);
HqlBuilder fromFetch(String joinAlias, String joinRelationship, String alias);
HqlBuilder where(String alias, String property, Operator operator, Object value);
HqlBuilder where(String alias, Operator operator, Object value);
HqlBuilder where(String alias1, Operator operator, String alias2);
HqlBuilder whereIn(String alias, String property, Set<?> values);
HqlBuilder whereIn(String alias, Set<?> values);
HqlBuilder where(Clause clause);
HqlBuilder orderBy(String alias, String property);
HqlBuilder orderBy(String alias, SortDirection sortDirection);
HqlBuilder orderBy(String alias, String property, SortDirection sortDirection);
String toHql();
...
答案 10 :(得分:0)
现在也可以使用标准JPA Type Safe查询,标准较低但也很好Object Query
示例:
JPA Type Safe
EntityManager em = ...
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Stock> c = qb.createQuery(Stock.class);
Root<Stock> = c.from(Stock.class);
Predicate condition = qb.eq(p.get(Stock_.id), id);
c.where(condition);
TypedQuery<Stock> q = em.createQuery(c);
List<Stock> result = q.getResultList();
对象查询
EntityManager em = ...
ObjectQuery<Stock> query = new GenericObjectQuery<Stock>(Stock.class);
Stock toSearch = query.target();
query.eq(toSearch.getId(),id);
List<Stock> res = (List<Stock>)JPAObjectQuery.execute(query, em);