Looking for an HQL builder (Hibernate Query Language)

后端 未结 11 902
-上瘾入骨i
-上瘾入骨i 2021-02-04 16:45

I\'m looking for a builder for HQL in Java. I want to get rid of things like:

StringBuilder builder = new StringBuilder()
    .append(\"select stock from \")
            


        
相关标签:
11条回答
  • 2021-02-04 17:31

    @Sébastien Rocca-Serra

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

    That's just a join. Hibernate does it automatically, if and only if you've got the mapping between Stock and Bonus setup and if bonus is a property of Stock. Criteria.list() will return Stock objects and you just call stock.getBonus().

    Note, if you want to do anything like

    select stock
    from com.something.Stock as stock
    where stock.bonus.value > 1000000
    

    You need to use Criteria.createAlias(). It'd be something like

    session.createCriteria(Stock.class).createAlias("bonus", "b")
       .add(Restrictions.gt("b.value", 1000000)).list()
    
    0 讨论(0)
  • 2021-02-04 17:35

    Take a look at the search package available from the hibernate-generic-dao project. This is a pretty decent HQL Builder implementation.

    0 讨论(0)
  • 2021-02-04 17:36

    @Sébastien Rocca-Serra
    Now we're getting somewhere concrete. The sort of join you're trying to do isn't really possible through the Criteria API, but a sub-query should accomplish the same thing. First you create a DetachedCriteria for the bonus table, then use the IN operator for someValue.

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

    This is equivalent to

    select stock
    from com.something.Stock as stock
    where stock.someValue in (select bonus.id from com.something.Bonus as bonus)
    

    The only downside would be if you have references to different tables in someValue and your ID's are not unique across all tables. But your query would suffer from the same flaw.

    0 讨论(0)
  • 2021-02-04 17:37

    For another type-safe query dsl, I recommend http://www.torpedoquery.org. The library is still young but it provides type safety by directly using your entity's classes. This means early compiler errors when the query no longer applies before of refactoring or redesign.

    I also provided you with an example. I think from your posts that you where trying to do a subquery restriction, so I based the exemple on that:

    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);
    
    0 讨论(0)
  • 2021-02-04 17:41

    Criteria API does not provide all functionality avaiable in HQL. For example, you cannot do more than one join over the same column.

    Why don't you use NAMED QUERIES? The look much more clean:

    Person person = session.getNamedQuery("Person.findByName")
                                 .setString(0, "Marcio")
                                 .list();
    
    0 讨论(0)
提交回复
热议问题