HQL是Hibernate Query Language的缩写,HQL的语法很像SQL的语法,但HQL是一种面向对象的查询语言。因此,SQL的操作对象是数据表和列等数据对象,而HQL的操作对象是类、实例、属性等。
HQL是完全面向对象的查询语言,因此可以支持继承和多态等特征
HQL查询的步骤:
1,获取 Hibernate Session 对象。
2,编写HQL语句。
3,以HQL为参数,调用Session的createQuery创建查询对象(如果HQL语句有参数,调用Query的set方法赋值)。
4,调用Query对象的list等方法返回实例。
如:
<span style="font-size:24px;"> LearningDAO learningDao=new LearningDAO(); Configuration cfg=new Configuration().configure(); SessionFactory sessionFactory=learningDao.getSessionFactory(); Session session=sessionFactory.openSession();//获得session对象 Transaction tran=session.beginTransaction(); Query query=session.createQuery("from Learning");//HQL语句,创建Query对象 List list=query.list(); for(int i=0;i<list.size();i++){ Learning l=(Learning)list.get(i); System.out.println(l.getId()); } </span>
HQL语句本身是不区分大小写的。也就是说,HQL语句的关键字和函数都是不区分大小写的。但HQL语句中所使用的包名、类名、实例名和属性名都区分大小写
1,HQL查询的from子句
from子句是最简单的HQL语句,也是最基本的HQL语句。from关键字后紧跟持久化类的类名,
例如:
from City ;表明从City持久化类中选出全部的实例。
大部分时候,推荐为该City的每个实例起别名。
例如:
from City as c
在上面的HQL语句中,City持久化类中的实例的别名为c,既然 c是实例名,因此也应该遵守Java的命名规则:第一个单词的首字母小写,后面每个单词的首字母大写。
命名别名时,as关键字是可选的,但为了增加可读性,建议保留。
例如:
from City c
from后还可同时出现多个持久化类,此时将产生一个笛卡儿积或跨表的连接。
2,HQL查询的select子句:
select 子句选择将哪些对象与属性返 回到查询结果集中.select子句用于确定选择出的属性,当然select选择的属性必须是from后持久化类包含的属性
select可以选择任意属性,不仅可以选择持久化类的直接属性,还可以选择组件属性包含的属性,
例如:
<span style="font-size:24px;">select p.name.firstName from Person as p</span>select也支持将选择出的属性存入一个List对象中,例如:
<span style="font-size:24px;">select new list(p.name , p.address) from Person as p</span>
<span style="font-size:24px;">select new ClassTest(p.name , p.address) from Person as p</span>
<span style="font-size:24px;">select p.name as personName from Person as p</span>
<span style="font-size:24px;">select new map(p.name as personName) from Person as p</span>在这种情形下,选择出的是Map结构,以personName为key,实际选出的值作为value。
3,HQL查询的聚集函数
HQL查询甚至可以返回作用于属性之上的聚集函数的计算结果:
select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) from Cat cat● avg,计算属性平均值。
HQL语句被设计成能理解多态查询,from后跟的持久化类名,不仅会查询出该持久化类的全部实例,还会查询出该类的子类的全部实例
下面的查询语句:
from Person as p
5,HQL查询的where子句
where子句允许你将返回的实例列表的范围缩小. 如果没有指定别名,你可以使用属性名来直接引用属性:
from Cat where name='Fritz'
如果指派了别名,需要使用完整的属性名:
from Cat as cat where cat.name='Fritz'
返回名为(属性name等于)'Fritz'的Cat类的实例。
复合属性表达式加强了where子句的功能,例如如下HQL语句:
from Cat cat where cat.mate.name like "kit%"
该查询将被翻译成为一个含有内连接的SQL查询,翻译后的SQL语句如下:
select * from cat_table as table1 cat_table as table2 where table1.mate = table2.id and table1.name like "kit%"
from Foo foo where foo.bar.baz.customer.address.city like"guangzhou%"
from Cat cat, Cat rival where cat.mate = rival.mate select cat, mate from Cat cat, Cat mate where cat.mate = mate
● in、not in、between、is null、is not null、is empty、is not empty、member of和not member of等。
● 简单的case、case ... when ... then ... else ... end和case、case when ... then ... else ... end等。
● 字符串连接符value1 || value2或使用字符串连接函数concat(value1 , value2)。
● 时间操作函数current_date()、current_time()、current_timestamp()、second()、minute()、hour()、day()、month()、year()等。
● HQL还支持EJB-QL 3.0所支持的函数或操作substring()、trim()、lower()、upper()、length()、locate()、abs()、sqrt()、bit_length()、coalesce()和nullif()等。
● 还支持数据库的类型转换函数,如cast(... as ...),第二个参数是Hibernate的类型名,或者extract(... from ...),前提是底层数据库支持ANSI cast()?和extract()。
● 如果底层数据库支持如下单行函数sign()、trunc()、rtrim()、sin()。则HQL语句也完全可以支持。
● HQL语句支持使用?作为参数占位符,这与JDBC的参数占位符一致,也可使用命名参数占位符号,方法是在参数名前加冒号 :,例如 :start_date和:x1等。
● 当然,也可在where子句中使用SQL常量,例如'foo'、69、'1970-01-01 10:00: 01.0'等。
● 还可以在HQL语句中使用Java public static final 类型的常量,例如eg.Color.TABBY。
除此之外,where子句还支持如下的特殊关键字用法。
● in与between...and可按如下方法使用:
from DomesticCat cat where cat.name between 'A' and 'B' from DomesticCat cat where cat.name in ( 'Foo','Bar','Baz')
from DomesticCat cat where cat.name not between 'A' and 'B' from DomesticCat cat where cat.name not in ( 'Foo','Bar','Baz' )
from DomesticCat cat where cat.name is null; from Person as p where p.address is not null;
● size关键字用于返回一个集合的大小,例如:
from Cat cat where cat.kittens.size > 0 from Cat cat where size(cat.kittens) > 0
from Calendar cal where maxelement(cal.holidays) > current date from Order order where maxindex(order.items) > 100 from Order order where minelement(order.items) > 10000
//操作集合元素 select mother from Cat as mother, Cat as kit where kit in elements(foo.kittens) //p的name属性等于集合中某个元素的name属性 select p from NameList list, Person p where p.name = some elements(list.names) //操作集合元素 from Cat cat where exists elements(cat.kittens) from Player p where 3 > all elements(p.scores) from Show show where 'fizard' in indices(show.acts)
//items是有序集合属性,items[0]代表第一个元素 from Order order where order.items[0].id = 1234 //holidays是map集合属性,holidays[national day]代表其中一个元素 select person from Person person, Calendar calendar where calendar.holidays['national day'] = person.birthDay and person.nationality.calendar = calendar //下面同时使用list 集合和map集合属性 select item from Item item, Order order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 select item from Item item, Order order where order.items[ maxindex(order.items) ] = item and order.id = 11
查询返回的列表(list)可以根据类或组件属性的任何属性进行排序,例如:
from Person as p order by p.name, p.age
from Person as p order by p.name asc , p.age desc如果没有指定排序规则,默认采用升序规则。即是否使用asc关键字是没有区别的,加asc是升序排序,不加asc也是升序排序。
7,group by子句
返回聚集值的查询可以对持久化类或组件属性的属性进行分组,分组所使用的group by子句。看下面的HQL查询语句:
select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color
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)