HQL是Hibernate Query Language的缩写,HQL的语法很像SQL的语法,但HQL是面向对象的查询语句;
使用HQL查询按如下步骤:
1、获取HibernateSession对象;
2、编写HQL语句;
3、以HQL语句作为参数,调用Session的createQuery方法创建查询对象;
4.如果HQL语句含有参数,调用Query的SetXXX方法为参数赋值;
5.调用Query对象的List等方法遍历查询结果;
from是最简单的也是最基本的HQL语句,from关键字后紧跟持久化类名。例如:
from Person
大部分时候,推荐为该Person的每个实例另起别名。如下:
from Person as p
持久化类中的实现的别名为p,既然p是实例名,因此也应该遵守Java的命名规则,第一个单词的字母为小写,后面每个单词的首字母大写;
select p.name from Person as p
select可以选择任意属性,不仅可能选择持久化类的直接属性,还可以选择引用属性包含的属性。如下:
select p.name.firstName from Person as p
select也支持将选择的属性存入到一个List对象中。如下:
select new list(p.name,p.address) from Person as p;
另外,select甚至可以将选择出的属性直接封装成对象,如下:
select new ClassTest(p.name,p.address) from Person as p;
前提是ClassTest支持p.name p.address 的构造器,假如这个二参数的类型是String类型,那么ClassTest的构造器如下形式:
ClassTest(String name,String address);
select还支持给选中的属性命名别名
select p.name as name from Person as p;
avg:计算属性平均值
count:统计选择对象的数量
max:统计属性值的最大值
min:统计属性值的最小值
sun:计算属性值的总和
如下:
select count(*) form Person as p; select max(p.age) from Person as p;
select子句还支持字符串连接、算数运算符及SQL函数。如下:
select p.name || "" || p.address from Person as p;
此外,select子句使用distinct 和 all 关键字,此时的效果和SQL中的效果完成相同;
HQL语句被设计成能理解多态查询,其from后跟的持久化类名不仅会查询出该持久化对全部实例,还会查询出该类中子类的全部实例;
from Person as p;
HQL语句:
from Person as p where p.name like "tom%"; from Cat as cat where cat.mate.name like "kit%":
1、数学去处符+,-,*,/等;
2、二进制比较运算符=、=> 、<=、 <> 、!= 、like等;
3、逻辑运算拊 and 、 or、not 等;
4、in ,not in、between , is null, is not null, is empty, is not empty , member of and not emeber of 等;
5、简单的 case, case ...when...then...else.....end 和case, case when ....then....else....end等;
6、字符串连接符 value1 || value2 或者使用字符串连接函数concat(value1,value2).
7、时间操作函数:current_date() current_time() current_timestamp() second() minute() hour() day() month() year()等;
8、HQL还支持EJB-QL3.0支持的函数或操作:substring() trim() lower() upper() length() locate() abs() sqrt() bit_length() coalesce() 和 nullif()等;
9、HQL语句支持使用 ? 作为参数点位符 这与JDBC的参数点位符一致,也可以使用命名参数点位符,方法是在参数名闪加冒号“:”如:start_date ,:name;
in与 between ... end 如下:
from Person as p where p.name between 'A' and ‘B’; from Person as p where p.name in ('A','B','C');
not in 和not between ....end 如下:
from Person as p where p.name not between 'A' and ‘B’; from Person as p where p.name not in ('A','B','C');
如果在配置文件中使用要配置如下:
<property name="hibernate.query.substitutions">true 1, false 0</property>
from Person as p order by p.name,p.age
查询结果返回List
select cat.color ,sum(cat.weight), count(cat) from Cat as cat group by cat.color;
having子句用于对分组进行过滤。如下:
select cat.color ,sum(cat.weight), count(cat) from Cat as cat group by cat.color having cat.color in(eg.Color.TABBY,eg.Color.BLACK);
having子句只能在group by 中使用;
from Cat as cat where not(cat.name,cat.color) in (select cat.name,cat.color,from DomesticCat as cat);
对于集合属性,Hibernate默认采用延迟加载策略,例如:对于持久化类Person,有集合属性scores。加载Person实例时,默认不会加载scores属性,如果Session被关闭,则Person实例将无法访问关联的scores属性;
为了解决该问题,可以在Hibernate映射文件中取消延迟加载,或者用使用fetch join如下:
from Person as p join p.scores;
上面的fetch语句会初始化Person的scores集合属性。
如果使用了属性级别的延迟加载,可以用fetch all properties 来强制Hibernate立即抓取那些原本需要延迟加载的属性。如下:
from Documnet fetch all properties order by name; from Documnet as doc fetch all properties where lower(doc.name) like '%cats%';
HQL还支持将查询所用的HQL语句放到配置文件中,而不是代码中,通过这种方式,可以大提高程序的解耦。
下面是用query 元素定义命名查询的配置文件代码:
<query name="myNameQuery"> from Person as p where p.age > ? </query>
程序调用:
sesion.getNameQuery("myNameQuery").setInteger(0,20).list();
<sql-query name="mySqlQuer"> <return alias="s" class="Student"/> SELECT {s.*} from student as s where s.name like "张三"; </sql-query>
程序调用:
sesion.getNameQuery("mySqlQuer").setInteger(0,20).list();
<sql-query name="selectAllEmployees_SP" callable="true"> <return alias="emp" class="Employment">//返回是这个类的实例 <!--依次定义每列与实体类属性的引用属性--> <return-property name="employee" colum="EMPLOYEE"/> <!--将二列值映射到一个关联类的引用属性--> <return-property name="salary" > <!--映射列与引用属性之间的关联--> <return-colum name="VALUE"/> <return-colum name="CURRENCY"/> </return> </return> </sql-query>