Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不
要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查
询,它可以理解如继承、多态和关联之类的概念。
看个示例,看看sql和HQL的相同与不同:
Sql:select * fromtbl_user where uuid=‘123’
HQL:select Object(o)from UserModel o where o.uuid=‘123’
1) HQL对Java类和属性是大小写敏感的,对其他不是大小写敏感的。
2) 基本上sql和HQL是可以转换的,因为按照Hibernate的实现原理,最终运行的还是sql,只不过是自动生成的而已。
3) HQL支持内连接和外连接
4) HQL支持使用聚集函数,如:count、avg、sum、min、max等
5) HQL支持order by 和 group by
6) HQL支持条件表达式,如:in、like、between等
1) 直接返回对象集合,形如:select o from UserModel o
2) 返回某个特定类型的集合,形如:select o.name from UserModel o
3) 返回Object[],形如:select o.uuid,o.name from UserModel o
4) 返回List,形如:select new List(o.uuid,o.name) from UserModel o
5) 返回任意的对象,形如:select new cn.javass.h3.hello.A(o.uuid,o.name) from UserModel o ,这要求A对象有一个构造方法是传入这两个参数
6) 返回Map类型,形如:select new Map(o.uuid as Id,o.name as N) from UserModel o ,返回的结果,以as后面的别名做map的key,对应的数据做值
Session session = HibernateSessionFactory.getSession();
// Query query = session.createQuery("select d from Department d"); // List // for (Department department : list) { // System.out.println(department.getDeptname()); // }
// Query query = session.createQuery("select d.deptname from Department d"); // List // for (String string : list) { // System.out.println(string); // }
// Query query = session.createQuery("select d.deptid,d.deptname from Department d"); // List // for (Object[] strs : list) { // System.out.println(Arrays.toString(strs)); // }
// Query query = session.createQuery("select new List(d.deptid,d.deptname) from Department d"); // List // for (List // for (String string : list2) { // System.out.println(string); // } // }
Query query = session.createQuery("select new Map(d.deptid as id,d.deptname as name) from Department d");
List
for (Map System.out.println(map.toString()); } |
1) 直接from对象,形如: from UserModel
2) 可以分配别名,形如:from UserModel as um , as关键字可以省略
3) 如果from后面有多个对象,形如:from UserModel,DepModel ,相当于多表联合查询,返回他们的笛卡尔积
Query query = session.createQuery("from Department,Employee");
List
for (Object[] objects : list) { Department department = (Department) objects[0]; Employee employee = (Employee) objects[1]; System.out.println(department); System.out.println("------------"); System.out.println(employee); } |
1) 受支持的有avg,sum,min,max,count
2) 关键字 distinct 与all 也可以使用,它们具有与 SQL 相同的语义,比如:
selectcount(distinct o.name) from UserModel o
1) 如果前面没有指派别名,那就直接使用属性名
2) 如果指派了别名,必须使用别名.属性的方式
3) 在where子句中允许使用的表达式包括大多数在 SQL中使用的表达式,包括:
a) 数学运算符 +,-,*,/
b) 二进制比较运算符 =, >=, <=, <>, !=, like
c) 逻辑运算符 and,or,not
d) 括号 ( ),表示分组
e) in, not in, between, is null,is not null, is empty, is not empty, member of and not member of
f) 字符串连接符 ...||... or concat(...,...)
g) current_date(), current_time(),and current_timestamp()
h) second(...)、minute(...)、hour(...)、day(...)、month(...) 和 year(...)
i) EJB-QL 3.0 定义的任何功能或操作符:substring(),trim(), lower(), upper(), length(),locate(), abs(), sqrt(), bit_length(), mod()
j) coalesce() 和 nullif()
k) str() 把数字或者时间值转换为可读的字符串
l) cast(... as ...),其第二个参数是某 Hibernate类型的名字,以及extract(... from ...),只要 ANSI cast() 和 extract() 被底层数据库支持
m) HQL index() 函数,作用于 join 的有序集合的别名。
n) HQL 函数,把集合作为参数:size(),minelement(), maxelement(), minindex(), maxindex(),还有特别的 elements()和 indices 函数,可以与数量词加以限定:some, all, exists, any, in。
o) 任何数据库支持的SQL 标量函数,比如sign(), trunc(), rtrim(), sin()
p) JDBC 风格的参数传入 ?
q) 命名参数:name,:start_date,:x1
r) SQL 直接常量 'foo',69, 6.66E+2, '1970-01-01 10:00:01.0'
s) Java public static final 类型的常量 eg.Color.TABBY
1) 对于返回聚集值的查询,可以按照任何属性进行分组
2) 可以使用having子句
3) sql中的聚集函数,可以出现在having子句中
4) group by 子句与 order by 子句中都不能包含算术表达式
5) 不能group by 某个实体对象,必须明确的列出所有的聚集属性
查询返回的列表(list)可以按照一个返回的类或组件(components)中的任何属性进行排序,可选的 asc 或 desc 关键字指明了按照升序或降序进行排序。
对于支持子查询的数据库,Hibernate支持在查询中使用子查询。一个子查询必须被圆括号包围起来。
1) Hibernate可以在相关联的实体间使用join,类似于sql,支持inner join、left outerjoin、right outer join、full join(全连接,并不常用)。
2) inner join可以简写成join,left outerjoin 和right outer join在简写的时候可以把outer去掉。
通过 HQL 的 with 关键字,你可以提供额外的 join条件。
如:from Cat as cat left join cat.kittens as kitten with
kitten.bodyWeight > 10.0
可以要求立即返回关联的集合对象,如:
from Cat as cat
innerjoin fetch cat.mate
left join fetch cat.kittens