ITEEDU

From Gossip@caterpillar

Hibernate Gossip: 基本查询

使用HQL查询最简单的例子,就是查询指定类别对应表格的所有数据,例如:
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User");

List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    User user = (User) iterator.next();
    System.out.println(user.getId() + "\t" + user.getAge() + "\t" + user.getName());
}
也可以指定类别的全名,例如:
Query query = session.createQuery("from onlyfun.caterpillar.User");
HQL本身不区分大小写,不过要注意类别的名称必须区分大小写。

在查询类别对应的表格时,需注意到继承的问题,Hibernate会自动判定继承关系,如果查询的类别是某类别的父类别,则会返回与父类别、子类别对应的 所有表格数据,例如如果查询java.lang.Object,由于Object在Java中是所有类别的父类别,所以下面这个查询会返回数据库中所有表 格的资料:
Query query = session.createQuery("from java.lang.Object");
如果要针对某个属性作查询,则可以如下:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User as user");

List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    System.out.println(iterator.next());
}
如果要查询两个以上的属性,则如下,查询的结果会以数组的方式传回:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.age, user.name from User as user");

List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    Object[] obj = (Object[]) iterator.next();
    System.out.println(obj[0] + "\t" + obj[1]);
}
如果User类别提供有适当的建构方法,则可以在使用HQL时直接指定新建一个对象传回,例如若User如下设计:
package onlyfun.caterpillar;
public class User {
    private Integer id;
    private String name;
    private Integer age;
    
    public User() {
    }
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    ....
}
则在使用HQL查询时可以如下:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select new User(user.name, user.age) from User as user");

List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    User user= (User) iterator.next();
    System.out.println(user.getAge() + "\t" + user.getName());
}
要注意的是,这个返回的User实例并未与数据库有任何关联,可以试着取得id属性,可以发现它的值是nul,如果试图使用Session的saveOrupdate()方法,则会新增一笔数据而不是更新原有的数据。

可以使用distinct去除数据重复的记录:
Query query = session.createQuery("select distinct user.age from User as user");
List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    System.out.println(iterator.next());
}
您也可以在HQL中使用函式,例如取得资料的笔数:
Query query = session.createQuery("select count(*) from User as user");
List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    System.out.println(iterator.next());
}
使用avg()取得属性的平均值:
Query query = session.createQuery("select avg(user.age) from User as user");
List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    System.out.println(iterator.next());
}
使用upper()函式将字符串转为大写:
Query query = session.createQuery("select upper(user.name) from User as user");
List names = query.list();
Iterator iterator =  names.iterator();
while(iterator.hasNext()) {
    System.out.println(iterator.next());
}
可以一并参考 Query 的使用。