Hibernate支持强大且易于使用的面向对象查询语言(HQL)。 如果希望通过编程的方式创建查询,Hibernate提供了完善的按条件(Query By Criteria, QBC)以及按样例(Query By Example, QBE)进行Hibernate查询的功能。 你也可以用原生SQL(native SQL)描述Hibernate查询,Hibernate额外提供了将结果集(result set)转化为对象的支持。
1. 大小写敏感性问题
除了Java类与属性的名称外,查询语句对大小写并不敏感。如:SeLeCT 与 sELEct 以及 SELECT 是相同的,但是 com.fendou.domain.User 并不等价于
com.fendou.domain.user并且 user.name 也不等价于 user.Name。
2. from子句
HQL和原生SQL(native SQL)查询要通过为org.hibernate.Query的实例来表达。 这个接口提供了参数绑定、结果集处理以及运行实际查询的方法。 你总是可以通过当前Session获取一个Query对象:
Query query=session.createQuery(“hql”);
Hibernate中最简单的查询语句的形式如下 from User
大多数情况下, 你需要指定一个别名, 原因是你可能需要 在查询语句的其它部分引用到User
from User as u
关键字as 是可选的,我们也可以这样写:from User u
List users = session.createQuery( "from User as u ") .list();
List users = session.createQuery( " from User as u r where u.name = ?")
.setString(0, name) .list();
在where子句中允许使用的表达式包括 大多数你可以在SQL使用的表达式种类:
数学运算符+, -, *, /
二进制比较运算符=, >=, <=, <>, !=, like
逻辑运算符and, or, not
in, not in, between, is null, is not null, is empty, is not empty, member of and not member of
"简单的" case, case ... when ... then ... else ... end,和 "搜索" case, case when ... then ... else ... end
字符串连接符...||... or concat(...,...)
current_date(), current_time(), current_timestamp()
second(...), minute(...), hour(...), day(...), month(...), year(...),
一个查询通常在调用list()时被执行,执行结果会完全装载进内存中的一个集合(collection)。 查询返回的对象处于持久(persistent)状态。如果你知道的查询只会返回一个对象,可使用list()的快捷方式uniqueResult()。 注意,使用集合预先抓取的查询往往会返回多次根对象(他们的集合类都被初始化了)。你可以通过一个集合来过滤这些重复对象。
3. 绑定参数
接口Query提供了对命名参数(named parameters)、JDBC风格的问号(?)参数进行绑定的方法。 不同于JDBC,Hibernate对参数从0开始计数。 命名参数(named parameters)在查询字符串中是形如:name的标识符。 命名参数(named parameters)的优点是:
命名参数(named parameters)与其在查询串中出现的顺序无关
它们可在同一查询串中多次出现
它们本身是自我说明的
1. // JDBC风格的问号(?)参数绑定方法positional parameter
Query q = sess.createQuery("from User u where u.name = ?");
q.setString(0, "Izi");
List users = q.list();
2. //命名参数named parameter (preferred)
Query q = sess.createQuery("from User u where u.name = :name");
q.setString("name", "Fritz");
List users = q.list();
3. //命名集合参数named parameters list
List names = new ArrayList();
names.add("Izi");
names.add("Fritz");
Query q = sess.createQuery("from User u where u.name in (:namesList)");
q.setParameterList("namesList", names);
List users = q.list();
4. 迭代式获取结果(Iterating results)
某些情况下,你可以使用iterate()方法得到更好的性能。 这通常是你预期返回的结果在session,或二级缓存(second-level cache)中已经存在时的情况。 如若不然,iterate()会比list()慢,而且可能简单查询也需要进行多次数据库访问: iterate()会首先使用1条语句得到所有对象的持久化标识(identifiers),再根据持久化标识执行n条附加的select语句实例化实际的对象。
public List queryUsersubp(){
Session session= HibernateUtil.getSession();
String hql="select u.name, u.pass from User u";
Query query=session.createQuery(hql);
List users=query.list();
// Iterator it= users.iterator();
// while(it.hasNext()){
// Object[] count=(Object[])it.next();
// System.out.println(count[0]+"-"+count[1]);
// }
return users;
}
5. HQL中使用一些函数来进行结果统计
List results =session.find("select count(*), avg(u.age) from User as u");
ListIterator iterator = results.listIterator();
Object[] rows = (Object[]) iterator.next();
System.out.println("资料笔数: " + rows[0] + "\n平均年龄: " + rows[1]);