问题
I have a table called Gift, which has a one-to-many relationship to a table called ClickThrough - which indicates how many times that particular Gift has been clicked. I need to query for all of the Gift objects, ordered by ClickThrough count. I do not need the ClickThrough count returned, as I don't need anything done with it, I just want to use it for purposes of ordering.
I need the query to return a List of Gift objects directly, just ordered by ClickThrough count. How do I do this using the Criteria API? I can find a lot of documentation out there on similar information to this, but nothing quite like what I need.
回答1:
If you want to return a list of entities or properties in combination with a count you will need a group by. In criteria this is done through ProjectionList
and Projections
. e.g.
final ProjectionList props = Projections.projectionList();
props.add(Projections.groupProperty("giftID"));
props.add(Projections.groupProperty("giftName"));
props.add(Projections.count("giftID"), "count"); //create an alias for the count
crit.setProjection(props);
crit.add(Order.desc("count")); //use the count alias to order by
However, since you're using ProjectionList
you will also need to use AliasToBeanConstructorResultTransformer.
回答2:
Note for anyone else that comes through here looking to order by a property/column:
When using the approaches mentioned here, no results were found. The fix was to use criteria.addOrder(Order.asc(property));
instead. Notice the difference is to use addOrder
, rather than add
;
I've had this issue several times after running here for a quick reference.
回答3:
You have a one-to-many relationship from Gift to ClickThrough so I assume each ClickThrough is a record with some datetime or other information associated with it. In this case, I would add a "count" field to your mapping file and attach the ordering to the criterion:
criterion.add(Order.asc(count)))
The mapping property looks something like:
<property name="count" type="integer" formula="(select count(*) from Gift g inner join ClickThrough ct on ct.gift_id=g.id where g.id=ID)"/>
If you can't or don't want to change the mapping file, you could use Collections.sort()
with a Comparator
though it seems less efficient having to return so much data from the DB.
来源:https://stackoverflow.com/questions/5112560/hibernate-criteria-order-by