问题
I have a rather complex query which works in SQL, but I would like to express this in HQL for portability. I'm going to fetch a user configured preference value if they exist, if not I must use a default value. This value must be subtracted from current date and the matched against a column in the table which I'm interested in:
select d.id, d.guid, d.deletetimestamp, u.id
from descriptor d, ownerkey ow, user u
where
d.parentid in
(select td.id
from descriptor td, store s
where s.type = 'Trash'
and s.descriptorid = td.id
)
and d.ownerkeyid = ow.id
and ow.ownerid = u.id
and
(
(d.deletetimestamp < CURRENT_TIMESTAMP() - INTERVAL
(select pv.value
from preferencevalue pv, userpreference up
where u.id = up.userid
and up.preferenceid = 26
and up.value = pv.id)
DAY)
or
(d.deletetimestamp < CURRENT_TIMESTAMP() - INTERVAL
(select cast(pv.value as SIGNED)
from preferencevalue pv, defaultpreference dp
where dp.preferenceid = 26
and not exists(select up.userid from userpreference up where u.id = up.userid and up.preferenceid = 26)
and dp.value = pv.id)
DAY)
)
I'm trying to construct this by using the Criteria API which seems to include most of the logical operators that I need (equals, larger than, or, isEmpty/isNull), but not sure how I would express all these parts.
Using a view is not an option at this point since we're using MySQL as the production database while the integration tests are running with H2 inmemory database. I'm not able to get find the sata substract function in H2 while MySQL do support this.
The select fields isn't important since they have only been used for testing purposes.
回答1:
- you can use
Restrictions.disjunction()
for or -andRestrictions.conjuction()
for and clauses. - To reference a certain property of an entity (like pv.value) you can use
Projections.property("value")
- for the casting I'm not sure, perhaps using the
@Formula
annotation on your entity? But this is a hibernate and not a JPA annotation. - as far as I know there is no equivalent for
INTERVAL
in hibernate but in such cases (maybe also for the above cast) you could useRestrictions.sqlRestriction("some sql...")
It will be a challenge putting all of this together to transform your query to hibernate criteria.
greetz,
Stijn
来源:https://stackoverflow.com/questions/4440576/how-to-construct-advanced-hibernate-query-with-or-and-summarize-functions