如何将此本机 SQL 查询转换为 HQL
How to transform this native SQL query to an HQL
所以我有这个复杂的原生 SQLQuery:
string hql =
@"SELECT *
FROM
(SELECT a.*, rownum r__
FROM
(select f2.filmid,
f2.realisateurid,
f2.titre,
f2.annesortie,
f2.langue,
f2.duree,
f2.resume,
f2.poster,
f2.qtytotal,
f2.qtydisponible from film f2
where f2.filmid in (
select distinct f.filmid
from film f, filmpays fp, pays p, filmgenre fg, genre g, informationpersonnel director, role r, informationpersonnel actor
where f.filmid = fp.filmid
and fp.paysid = p.paysid
and f.filmid = fg.filmid
and fg.genreid = g.genreid
and f.realisateurid = director.personelid
and f.filmid = r.filmid
and r.personelid = actor.personelid
and f.qtydisponible > 0
and upper(f.titre) LIKE :titre
and f.annesortie >= :anneeLow AND f.annesortie <= :anneeHigh
and upper(g.Nomgenre) LIKE :genre
and upper(f.Langue) LIKE :langue
and upper(p.Nom) LIKE :pays
and upper(director.nom) LIKE :realisateur
and upper(actor.nom) LIKE :acteur)
order by f2.annesortie DESC, f2.titre) a
WHERE rownum < ((:page * 8) +1 ))
WHERE r__ >= (((:page - 1) *8) +1) ";
/*Begin transaction */
ITransaction tx = s.BeginTransaction();
IQuery query = s.CreateQuery(hql);
query.SetString("titre", "%" + sp.Title.ToUpper() + "%");
query.SetInt32("anneeLow", sp.YearLow);
query.SetInt32("anneeHigh", sp.YearHigh);
query.SetString("pays", "%" + sp.Country.ToUpper() + "%");
query.SetString("langue", "%" + sp.Lang.ToUpper() + "%");
query.SetString("genre", "%" + sp.Genre.ToUpper() + "%");
query.SetString("realisateur", "%" + sp.Director.ToUpper() + "%");
query.SetString("acteur", "%" + sp.Actor.ToUpper() + "%");
query.SetInt32("page", page);
IList<Film> movies = query.List<Film>();
tx.Commit();
return movies;
我正在尝试以 100% hql 的方式编写
类似于
IList<Cat> moreCats = sess.CreateQuery(
"from Cat as cat where " +
"cat.Name = 'Fritz' or cat.id = :id1 or cat.id = :id2"
).SetInt64("id1", id1)
.SetInt67("id2", id2)
.List<Cat>();
在查阅了 hql 文档后,我了解了如何在 hql 中进行简单的小查询,但是如果我有一个来自另一个 select 的复合体 select ,就像我的查询一样,我应该怎么做继续 ?
谢谢
HQL支持where语句中的子查询,所以where中的子查询应该不会出问题。
我认为您的 from 语句中的子查询没有必要,您应该能够更改您的查询以不再拥有它。
删除查询的分页部分可能会有帮助。此分页应通过在 HQL 查询对象上调用 .SetFirstResult(indexCalculatedFromYourPage)
和 .SetMaxResults(yourPageSize)
来完成。
当然,您需要在您的实体上映射所有必需的列。您的大部分查询看起来已经与 HQL 兼容。
如果您也映射相关实体,则可以通过避免显式编写相关表的连接条件来简化 where 子查询。
注意:您的查询看起来像 "multi-criteria" 搜索查询。与其编写一个考虑所有参数(并支持它们为 empty/unspecified)的查询,动态编写查询以忽略未提供的参数通常更容易(顺便说一句,性能更好)。为此,最好使用 api 之类的查询 queryover or linq-to-nhibernate.
编辑:我现在意识到你已经将你的问题标记为 nhibernate (.Net) and hibernate (Java). The two api I have linked are for NHibernate. If you are using Java, then there is the hibernate-criteria api,也许还有其他我不知道的问题。
所以我有这个复杂的原生 SQLQuery:
string hql =
@"SELECT *
FROM
(SELECT a.*, rownum r__
FROM
(select f2.filmid,
f2.realisateurid,
f2.titre,
f2.annesortie,
f2.langue,
f2.duree,
f2.resume,
f2.poster,
f2.qtytotal,
f2.qtydisponible from film f2
where f2.filmid in (
select distinct f.filmid
from film f, filmpays fp, pays p, filmgenre fg, genre g, informationpersonnel director, role r, informationpersonnel actor
where f.filmid = fp.filmid
and fp.paysid = p.paysid
and f.filmid = fg.filmid
and fg.genreid = g.genreid
and f.realisateurid = director.personelid
and f.filmid = r.filmid
and r.personelid = actor.personelid
and f.qtydisponible > 0
and upper(f.titre) LIKE :titre
and f.annesortie >= :anneeLow AND f.annesortie <= :anneeHigh
and upper(g.Nomgenre) LIKE :genre
and upper(f.Langue) LIKE :langue
and upper(p.Nom) LIKE :pays
and upper(director.nom) LIKE :realisateur
and upper(actor.nom) LIKE :acteur)
order by f2.annesortie DESC, f2.titre) a
WHERE rownum < ((:page * 8) +1 ))
WHERE r__ >= (((:page - 1) *8) +1) ";
/*Begin transaction */
ITransaction tx = s.BeginTransaction();
IQuery query = s.CreateQuery(hql);
query.SetString("titre", "%" + sp.Title.ToUpper() + "%");
query.SetInt32("anneeLow", sp.YearLow);
query.SetInt32("anneeHigh", sp.YearHigh);
query.SetString("pays", "%" + sp.Country.ToUpper() + "%");
query.SetString("langue", "%" + sp.Lang.ToUpper() + "%");
query.SetString("genre", "%" + sp.Genre.ToUpper() + "%");
query.SetString("realisateur", "%" + sp.Director.ToUpper() + "%");
query.SetString("acteur", "%" + sp.Actor.ToUpper() + "%");
query.SetInt32("page", page);
IList<Film> movies = query.List<Film>();
tx.Commit();
return movies;
我正在尝试以 100% hql 的方式编写
类似于
IList<Cat> moreCats = sess.CreateQuery(
"from Cat as cat where " +
"cat.Name = 'Fritz' or cat.id = :id1 or cat.id = :id2"
).SetInt64("id1", id1)
.SetInt67("id2", id2)
.List<Cat>();
在查阅了 hql 文档后,我了解了如何在 hql 中进行简单的小查询,但是如果我有一个来自另一个 select 的复合体 select ,就像我的查询一样,我应该怎么做继续 ?
谢谢
HQL支持where语句中的子查询,所以where中的子查询应该不会出问题。
我认为您的 from 语句中的子查询没有必要,您应该能够更改您的查询以不再拥有它。
删除查询的分页部分可能会有帮助。此分页应通过在 HQL 查询对象上调用 .SetFirstResult(indexCalculatedFromYourPage)
和 .SetMaxResults(yourPageSize)
来完成。
当然,您需要在您的实体上映射所有必需的列。您的大部分查询看起来已经与 HQL 兼容。
如果您也映射相关实体,则可以通过避免显式编写相关表的连接条件来简化 where 子查询。
注意:您的查询看起来像 "multi-criteria" 搜索查询。与其编写一个考虑所有参数(并支持它们为 empty/unspecified)的查询,动态编写查询以忽略未提供的参数通常更容易(顺便说一句,性能更好)。为此,最好使用 api 之类的查询 queryover or linq-to-nhibernate.
编辑:我现在意识到你已经将你的问题标记为 nhibernate (.Net) and hibernate (Java). The two api I have linked are for NHibernate. If you are using Java, then there is the hibernate-criteria api,也许还有其他我不知道的问题。