通常,开发人员喜欢将HQL字符串文字散布在整个Java代码中,这种方法很难维护并且很难看。 幸运的是,Hibernate提出了一种称为“ 名称查询 ”的技术,它使开发人员可以将所有HQL放入XML映射文件或通过注释。
如何声明命名查询
HQL或本地SQL均支持命名查询。 看例子…
1. XML映射文件
映射文件中的HQL
<!-- stock.hbm.xml -->
<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" ...>
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true" />
</property>
...
</class>
<query name="findStockByStockCode">
<![CDATA[from Stock s where s.stockCode = :stockCode]]>
</query>
</hibernate-mapping>
映射文件中的本机SQL
<!-- stock.hbm.xml -->
<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" ...>
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true" />
</property>
...
</class>
<sql-query name="findStockByStockCodeNativeSQL">
<return alias="stock" class="com.mkyong.common.Stock"/>
<![CDATA[select * from stock s where s.stock_code = :stockCode]]>
</sql-query>
</hibernate-mapping>
您可以在“ hibernate-mapping ”元素中放置一个命名查询,但不要将其放置在“ class ”元素之前,Hibernate会提示无效的映射文件,所有命名查询都必须放置在“ class ”元素之后。
注意
关于CDATA,始终最好的做法是用CDATA包裹查询文本,以使XML解析器不会对某些特殊XML字符(例如'>',<'等)提示错误。
2.注释
注释中的HQL
@NamedQueries({
@NamedQuery(
name = "findStockByStockCode",
query = "from Stock s where s.stockCode = :stockCode"
)
})
@Entity
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {
...
注释中的本机SQL
@NamedNativeQueries({
@NamedNativeQuery(
name = "findStockByStockCodeNativeSQL",
query = "select * from stock s where s.stock_code = :stockCode",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {
...
在本机SQL中,必须声明' resultClass '以让Hibernate知道返回类型是什么,否则将导致异常“ org.hibernate.cfg.NotYetImplementedException:尚不支持纯本机标量查询 ”。
调用命名查询
在Hibernate中,您可以通过getNamedQuery方法调用命名查询。
Query query = session.getNamedQuery("findStockByStockCode")
.setString("stockCode", "7277");
Query query = session.getNamedQuery("findStockByStockCodeNativeSQL")
.setString("stockCode", "7277");
结论
命名查询是全局访问,这意味着查询的名称在XML映射文件或注释中必须唯一。 在实际环境中,将所有命名查询隔离到它们自己的文件中始终是一个好习惯。 另外,存储在Hibernate映射文件或注释中的命名查询比通过Java代码分散的查询更易于维护。
翻译自: https://mkyong.com/hibernate/hibernate-named-query-examples/