七、HQL查询的where子句
(1)where子句用于筛选选中的结果,缩小选择的范围。如果没有为持久化实例命名别名,则可以直接使用属性名来引用属性。
如下面两条HQL语句:
from Person where name like "tom%"
form Person as p where p.name like "tom%"
(2)复合属性表达式加强了where子句的功能,例如,如下的HQL语句:
from Cat cat where cat.mate.name like "kit%"
上面语句被翻译成以下含有内连接的SQL查询:
select * from cat_table as table1 cat_table as table2
where table1.mate = table2.mate
and table1.name like '''kit%'"
实际上这种用法使用了隐式连接查询,从Hibernate3.2.3之后,只有当cat,mate属性引用的是普通组件属性或者单独的关联实体时才可接着在后面使用点好(.)来引用mate属性,如cat,mate.name; 如果cat,mate是集合属性,Hibernate3.2.3以后的版本不支持这种用法。
"="号不仅可以被用来比较属性的值,也可以用来比较实例。
select cat,mate from Cat cat, Cat mate where cat.mate = mate
(3)在进行多态持久化的情况下,class关键字用来存取一个实例的鉴别值。嵌入where子句的Java类名,将被作为该类的鉴别值。
//执行多态查询时,默认会选出Cat及其所有子类的实例
//在如下HQL语句中,将只选出DomesticCat类的实例
from Cat cat where cat.class = DomesticCat
(4)当where子句中的运算符只支持基本类型或者字符串时,where子句中的属性表达式必须以基本类型或者字符串结尾,不要使用组件类型属性结尾,例如Account和Person属性,而Person有Name属性,Name属性有firstName属性。
如下所示:
//firstName是字符串
from Account as a where a.person.name.firstName like "dd%"
//下面是错误实例
from Account as a where a.person.name like "dd%"
八、表达式
1、HQL的功能非常丰富,where子句后支持的运算符,不仅包括SQL的运算符,也包括EJB-QL的运算符等。
where子句中允许使用大部分SQL支持的表达式,包括如下种类:
(1)字符串连接:如value1||value2,或使用字符串连接函数concat(value1, value2)
(2)简单的case,case...when...then...else...end和case,case when...then...else...end等。
(3)时间操作函数:current_date()、current_time、year()等。
(4)EJB-QL3.0的函数:substring()、trim()、abs()、sqrt()等。
(5)可在where子句中使用SQL常量。
(6)在HQL语句中使用Java中的public static final类型的常量,例如Color.RED
(7)HQL语句支持使用英文问号(?)作为参数占位符,这与JDBC的参数占位符一致;也使用命名参数占位符号,方法在参数名前加英文冒号(:),例如:start_date等。
(8)如果底层数据库支持单行函数,则HQL语句也完全可以支持。
(9)支持数据库的类型转换函数,如cast(... as ...),第二个参数是Hibernate的类型名,或者extract(... from ,,,),前提是底层数据库支持ANSI cast()和extract()。
2、如果在Hibernate配置文件中进行如下声明:
<property name="hibernate.query.substitutions">true 1,false 0</property>
上面的声明表明:HQL转换SQL语句时,将使用字符1和0来取代关键字true和false,然后将可以在表达式中使用布尔表达式。
3、有用的elements()和indices函数,用于返回指定集合的所有元素和所有索引。
4、在where子句中,有序集合(数组、List集合、Map对象)的元素可以通过【】运算符来访问。如下:
from Order order where order.items[0].id=1234
在【】中的表达式甚至可以是一个算式表达式。
5、结构变量:size、elements、indices等,只能在where子句中使用。
九、order by子句
查询返回的集合根据类或组件属性的任何属性进行排序。例如:
from Person as p order by p.name,p.age
还可以使用as或desc关键字指定升序或降序的排序规则。例如:
from Person as p order by p.name asc,p.age desc
如果没有指定排序规则,默认采用升序规则。
十、group by子句
返回聚集值的查询可以对持久化类或组件属性的进行分组,分组使用group by子句。看下面的HQL查询语句:
select cat,color,sum(cat.weight),count(cat) from Cat cat group by cat.color
其规则类似于SQL规则。
having子句用于对分组进行过滤,如下所示:
select cat,color,sum(cat.weight),count(cat) from Cat cat group by cat.color having cat.color in (eg.Color.TABBY,eg.Color.BLACK)
注意:group by子句与order by 子句中都不能包含算术表达式
(1)where子句用于筛选选中的结果,缩小选择的范围。如果没有为持久化实例命名别名,则可以直接使用属性名来引用属性。
如下面两条HQL语句:
from Person where name like "tom%"
form Person as p where p.name like "tom%"
(2)复合属性表达式加强了where子句的功能,例如,如下的HQL语句:
from Cat cat where cat.mate.name like "kit%"
上面语句被翻译成以下含有内连接的SQL查询:
select * from cat_table as table1 cat_table as table2
where table1.mate = table2.mate
and table1.name like '''kit%'"
实际上这种用法使用了隐式连接查询,从Hibernate3.2.3之后,只有当cat,mate属性引用的是普通组件属性或者单独的关联实体时才可接着在后面使用点好(.)来引用mate属性,如cat,mate.name; 如果cat,mate是集合属性,Hibernate3.2.3以后的版本不支持这种用法。
"="号不仅可以被用来比较属性的值,也可以用来比较实例。
select cat,mate from Cat cat, Cat mate where cat.mate = mate
(3)在进行多态持久化的情况下,class关键字用来存取一个实例的鉴别值。嵌入where子句的Java类名,将被作为该类的鉴别值。
//执行多态查询时,默认会选出Cat及其所有子类的实例
//在如下HQL语句中,将只选出DomesticCat类的实例
from Cat cat where cat.class = DomesticCat
(4)当where子句中的运算符只支持基本类型或者字符串时,where子句中的属性表达式必须以基本类型或者字符串结尾,不要使用组件类型属性结尾,例如Account和Person属性,而Person有Name属性,Name属性有firstName属性。
如下所示:
//firstName是字符串
from Account as a where a.person.name.firstName like "dd%"
//下面是错误实例
from Account as a where a.person.name like "dd%"
八、表达式
1、HQL的功能非常丰富,where子句后支持的运算符,不仅包括SQL的运算符,也包括EJB-QL的运算符等。
where子句中允许使用大部分SQL支持的表达式,包括如下种类:
(1)字符串连接:如value1||value2,或使用字符串连接函数concat(value1, value2)
(2)简单的case,case...when...then...else...end和case,case when...then...else...end等。
(3)时间操作函数:current_date()、current_time、year()等。
(4)EJB-QL3.0的函数:substring()、trim()、abs()、sqrt()等。
(5)可在where子句中使用SQL常量。
(6)在HQL语句中使用Java中的public static final类型的常量,例如Color.RED
(7)HQL语句支持使用英文问号(?)作为参数占位符,这与JDBC的参数占位符一致;也使用命名参数占位符号,方法在参数名前加英文冒号(:),例如:start_date等。
(8)如果底层数据库支持单行函数,则HQL语句也完全可以支持。
(9)支持数据库的类型转换函数,如cast(... as ...),第二个参数是Hibernate的类型名,或者extract(... from ,,,),前提是底层数据库支持ANSI cast()和extract()。
2、如果在Hibernate配置文件中进行如下声明:
<property name="hibernate.query.substitutions">true 1,false 0</property>
上面的声明表明:HQL转换SQL语句时,将使用字符1和0来取代关键字true和false,然后将可以在表达式中使用布尔表达式。
3、有用的elements()和indices函数,用于返回指定集合的所有元素和所有索引。
4、在where子句中,有序集合(数组、List集合、Map对象)的元素可以通过【】运算符来访问。如下:
from Order order where order.items[0].id=1234
在【】中的表达式甚至可以是一个算式表达式。
5、结构变量:size、elements、indices等,只能在where子句中使用。
九、order by子句
查询返回的集合根据类或组件属性的任何属性进行排序。例如:
from Person as p order by p.name,p.age
还可以使用as或desc关键字指定升序或降序的排序规则。例如:
from Person as p order by p.name asc,p.age desc
如果没有指定排序规则,默认采用升序规则。
十、group by子句
返回聚集值的查询可以对持久化类或组件属性的进行分组,分组使用group by子句。看下面的HQL查询语句:
select cat,color,sum(cat.weight),count(cat) from Cat cat group by cat.color
其规则类似于SQL规则。
having子句用于对分组进行过滤,如下所示:
select cat,color,sum(cat.weight),count(cat) from Cat cat group by cat.color having cat.color in (eg.Color.TABBY,eg.Color.BLACK)
注意:group by子句与order by 子句中都不能包含算术表达式