在我的.hbm.xml中有两个查询。第一个检索表中的记录数:
<query name="Airframe.SearchCount"><![CDATA[
select
count(*)
from
AirframeBean as a inner join
a.manufacturer as m
where
m.name like :manufacturer and
a.description like :description and
((a.percentSize <= :sizeMax and
a.percentSize >= :sizeMin) or
a.percentSize is null) and
((a.wingSpanInches <= :spanMax and
a.wingSpanInches >= :spanMin) or
a.wingSpanInches is null) and
((a.recommendedAuwMinLbs <= :auwMax and
a.recommendedAuwMaxLbs >= :auwMin) or
a.recommendedAuwMaxLbs is null)
]]></query>
第二个使用偏移和限制逐页获取数据:
<query name="Airframe.SearchData"><![CDATA[
select
a
from
AirframeBean as a inner join
a.manufacturer as m
where
m.name like :manufacturer and
a.description like :description and
((a.percentSize <= :sizeMax and
a.percentSize >= :sizeMin) or
a.percentSize is null) and
((a.wingSpanInches <= :spanMax and
a.wingSpanInches >= :spanMin) or
a.wingSpanInches is null) and
((a.recommendedAuwMinLbs <= :auwMax and
a.recommendedAuwMaxLbs >= :auwMin) or
a.recommendedAuwMaxLbs is null)
]]></query>
查询几乎相同。唯一的区别是第一个以select count(*)
开头,第二个以select a
开头。有没有办法避免复制粘贴?
更新 主要问题是我需要Hibernate在启动时验证模式,映射和HQL查询。
答案 0 :(得分:4)
您可以这样做: -
命名查询
#SELECTOR#
是您的Java代码必须替换的占位符。
<query name="Airframe"><![CDATA[
select
#SELECTOR#
from
AirframeBean as a inner join
a.manufacturer as m
where
m.name like :manufacturer and
a.description like :description and
((a.percentSize <= :sizeMax and
a.percentSize >= :sizeMin) or
a.percentSize is null) and
((a.wingSpanInches <= :spanMax and
a.wingSpanInches >= :spanMin) or
a.wingSpanInches is null) and
((a.recommendedAuwMinLbs <= :auwMax and
a.recommendedAuwMaxLbs >= :auwMin) or
a.recommendedAuwMaxLbs is null)
]]></query>
Hibernate代码
public Long searchCount() {
String sql = getQueryString("Airframe").replace("#SELECTOR#", "count(*)");
return (Long) session.createSQLQuery(sql, args...).uniqueResult();
}
@SuppressWarnings("unchecked")
public List<AirframeBean> getAirframeBeans() {
String sql = getQueryString("Airframe").replace("#SELECTOR#", "a");
return session.createSQLQuery(sql, args...).list();
}
private String getQueryString(String namedQuery) {
return session.getNamedQuery(namedQuery).getQueryString();
}
答案 1 :(得分:1)
一个想法是,如果您决定升级到程序/注释驱动的持久性。一旦您将查询作为java HQL
字符串查询或DetachedStatement
促进重用是轻而易举的事。考虑使用HQL
的方案,您可以通过以下方式获得所需的效果:
String hql = ...
hql = hql.replace("count(*)", "a");
或者:
String hql = "from ...";
String q1 = "select count(*) " + hql;
String q2 = "select a " + hql;
另见How this SQL Query in hbm.xml file can be written in source code?
答案 2 :(得分:0)
另一个想法是使用Criteria API来管理分页而不是命名查询。 使用hibernate Criteria API,您可以使用方法setFirstResult()和setMaxResult()来定义要为表加载的数据组。
答案 3 :(得分:-1)
Criteria API是一种使用hibernate创建查询的不同方式,对于分页而言非常有用。
使用代码的一个例子是:
Criteria crit = session.createCriteria(AirframeBean.class);
crit.add(Restrictions.like("name", "manufacturer"));
crit.add(Restrictions.like("description", "yourDescription"));
crit.add(Restrictions.between("percentSize", "sizeMin", "sizeMax"));
ecc....
crit.setMaxResults(maxResults);
crit.setFirstResult(firstResult);
List result = crit.list()
要添加条件AND或OR,您可以使用:Restrictions.disjunction();或Restrictions.conjunction();
通过这种方式,您只使用java代码而不使用xml文件来管理和编写动态查询。