Chapter 15. SQL查询

You may also express queries in the native SQL dialect of your database. This is useful if you want to utilize database specific features such as the CONNECT keyword in Oracle. This also allows for a cleaner migration path from a direct SQL/JDBC based application to Hibernate. 你也可以直接使用你的数据库方言表达查询。在你想使用数据库的某些特性的时候,这是非常有用的, 比如Oracle中的CONNECT关键字。这也会扫清你把原来直接使用SQL/JDBC 的程序移植到Hibernate道路上的障碍。

15.1. Creating a SQL based Query

15.1. Creating a SQL based Query

SQL queries are exposed through the same Query interface, just like ordinary HQL queries. The only difference is the use of Session.createSQLQuery(). 和普通的HQL查询一样,SQL查询同样是从Query接口开始的。惟一的区别是使用Session.createSQLQuery()方法。

Query sqlQuery = sess.createSQLQuery("select {cat.*} from cats {cat}", "cat", Cat.class);
sqlQuery.setMaxResults(50);
List cats = sqlQuery.list();

The three parameters provided to createSQLQuery() are: 传递给createSQLQuer()的三个参数是:

  • the SQL query string SQL查询语句

  • a table alias name 表的别名

  • the persistent class returned by the query 查询返回的持久化类

The alias name is used inside the sql string to refer to the properties of the mapped class (in this case Cat). You may retrieve multiple objects per row by supplying a String array of alias names and a Class array of corresponding classes. 别名是为了在SQL语句中引用对应的类(本例中是Cat)的属性的。你也可以传递一个别名的String 数组和一个对应的Class的数组进去,每行就可以得到多个对象。

15.2. Alias and property references

The {cat.*} notation used above is a shorthand for "all properties". You may even list the properties explicity, but you must let Hibernate provide SQL column aliases for each property. The placeholders for these column aliases are the property name qualified by the table alias. In the following example, we retrieve Cats from a different table (cat_log) to the one declared in the mapping metadata. Notice that we may even use the property aliases in the where clause. 上面使用的{cat.*}标记是“所有属性的”的简写。你可以显式的列出需要的属性,但是你必须让Hibernate为每个 属性提供SQL列别名。这些列的的占位表示符是以表别名为前导,再加上属性名。下面的例子中,我们从一个其它的表(cat_log) 中获取Cat对象,而非Cat对象原本在映射元数据中声明的表。注意你在where子句中也可以使用 属性别名。

String sql = "select cat.originalId as {cat.id}, cat.mateid as {cat.mate}, cat.sex as {cat.sex}, cat.weight*10 as {cat.weight}, cat.name as {cat.name}"
    + " from cat_log cat where {cat.mate} = :catId"
List loggedCats = sess.createSQLQuery(sql, "cat", Cat.class)
	.setLong("catId", catId)
	.list();

Note: if you list each property explicitly, you must include all properties of the class and its subclasses! 注意: 如果你明确的列出了每个属性,你必须包含这个类和它的子类的属性! //??

15.3. 为SQL查询命名

Named SQL queries may be defined in the mapping document and called in exactly the same way as a named HQL query. 可以在映射文档中定义SQL查询的名字,然后就可以像调用一个命名HQL查询一样直接调用命名SQL查询。

List people = sess.getNamedQuery("mySqlQuery")
    .setMaxResults(50)
    .list();
<sql-query name="mySqlQuery">
    <return alias="person" class="eg.Person"/>
    SELECT {person}.NAME AS {person.name}, {person}.AGE AS {person.age}, {person}.SEX AS {person.sex}
    FROM PERSON {person} WHERE {person}.NAME LIKE 'Hiber%'
</sql-query>