代码之家  ›  专栏  ›  技术社区  ›  Sébastien RoccaSerra

正在寻找HQL生成器(Hibernate查询语言)

  •  7
  • Sébastien RoccaSerra  · 技术社区  · 18 年前

    HQL 在Java中。我想摆脱这样的事情:

    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 );
    

    我在谷歌上搜索了一下,却找不到。

    我写了一篇速记&哑的 HqlBuilder 这符合我目前的需求,但我很想找到一个比我一个人拥有更多用户和测试的网站。

    注意:我希望能够做这样或更多的事情,但我在Criteria API中没有做到:

    select stock
    from com.something.Stock as stock, com.something.Bonus as bonus
    where stock.someValue = bonus.id
    

    即,选择其属性为 someValue 任何

    谢谢

    11 回复  |  直到 18 年前
        1
  •  8
  •   Timo Westkämper    15 年前

    对于类型安全的方法,考虑 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集合。

        2
  •  7
  •   sblundy    18 年前

    不是吗 Criteria API 为你做吗?它看起来几乎和你要的一模一样。

        3
  •  5
  •   Community Mohan Dere    9 年前

    Sébastien Rocca-Serra
    现在我们有了具体的进展。您试图通过CriteriaAPI进行的连接实际上是不可能的,但是子查询应该完成同样的事情。首先,创建一个 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)
    

    唯一的缺点是如果在中有对不同表的引用 一些价值 并且您的ID在所有表中都不是唯一的。但您的查询也会有同样的缺陷。

        4
  •  5
  •   ebelanger    14 年前

    对于另一种类型安全的查询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);
    
        5
  •  4
  •   Alex Argo    18 年前

    看起来您想要使用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)));
    

    有关更多信息,请查看 Criteria Queries 从Hibernate文档

        6
  •  2
  •   Community Mohan Dere    9 年前

    @ Sébastien Rocca-Serra

    select stock
    from com.something.Stock as stock, com.something.Bonus as bonus
    where stock.bonus.id = bonus.id
    

    Stock Bonus 设置和如果 bonus . Criteria.list() 会回来的 股票 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()
    
        7
  •  2
  •   Marcio Aguiar    18 年前

    Criteria API未提供HQL中可用的所有功能。例如,不能对同一列执行多个联接。

    你为什么不使用 NAMED QUERIES ? 看起来更干净:

    Person person = session.getNamedQuery("Person.findByName")
                                 .setString(0, "Marcio")
                                 .list();
    
        8
  •  2
  •   Josh    17 年前

    我为OMERO编写了一个GPL'd解决方案,您可以轻松构建适合自己情况的解决方案。

    用法:

    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);
    

    HHH-879 HHH-2407 描述一个将两者统一起来的Hibernate分支。在此之后,重新访问Criteria API可能是有意义的

        9
  •  2
  •   Chuck Deal    16 年前
        10
  •  2
  •   Guillaume    16 年前

    "screensaver" project
    它不是Windows屏幕保护程序,而是一个 "

    它包含一个看起来相当不错的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();
    ...
    
        11
  •  0
  •   tglman    13 年前

    现在也可以使用标准 JPA Type Safe Object Query

    示例:

    JPA型保险柜

    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);