Hibernate学习(四)
HQL检索
指定别名
HQL语句类似于SQL语句,在HQL语句中也可以使用别名。别名使用关键自as指定,但在实际应用中,as关键字可以省略。代码如下:
@Test
public void aliasTest(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "from Customer as c where c.name = 'Jack'";
Query query = session.createQuery(hql);
List<Customer> cs = query.list();
for(Customer c:cs){
System.out.println(c);
}
t.commit();
}
投影查询
在通常的查询过程中,有时只需要查询部分属性,并不需要查询一个类的所有属性。如果仍然查询所有属性,是十分影响性能的。为此Hibernate中提供了投影查询,用来查询对象的部分属性。
在查询类对象的部分属性时,需要使用关键字select,并在其后加上需要查询的属性,然后就是from关键字和实体类名。代码如下:
@Test
public void protionQueryTest(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "select name,age from Customer";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
Iterator iter = list.iterator();
while(iter.hasNext()){
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + " " + obj[1]);
}
t.commit();
}
当检索对象是部分属性时,HIbernate返回的List中的每一个元素都是一个Object数组,而不再是Customer对象。在Object数据中,各个属性是顺序的。可以按照属性顺序从数组取出对应值。
动态实例查询
在投影查询时,返回的查询对象是一个数据对象,而且还要处理顺序,操作起来非常不方便。为了方便操作,提高检索效率,并且体现面向对象的思想,可以吧返回的结果重新组成一个实体的实例,这就是动态实例查询。代码如下:
@Test
public void dynamicQueryTest(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "select new Customer(name,age) from Customer";
Query query = session.createQuery(hql);
List<Customer> cs = query.list();
for(Customer c:cs){
System.out.println(c.getName() + " " + c.getAge());
}
t.commit();
}
使用这种方法是要在Customer中添加对应的构造方法。此时一定不要忘记额外添加一个空的构造方法。所填构造方法代码如下:
public class Customer {
public Customer() {
}
public Customer(String name, Integer age) {
this.name = name;
this.age = age;
}
}
条件查询
在实际应用中,通常需要根据指定的条件进行查询。这时,可以使用HQL语句提供的where字句进行查询,或者使用like关键字进行模糊查询。
依据参数形式的不同,可将条件查询分为两种:按参数位置进行查询和按参数名称进行查询。
- 按参数位置查询
按照参数进行查询时,需要在HQL语句中使用"?"来定义参数的位置,然后利用Query对象的方法进行赋值,此种方法与JDBC的PrepareStatement对象的参数绑定方式类似。代码如下:
@Test
public void paramQueryTest1(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "from Customer where name like ?";
Query query = session.createQuery(hql);
query.setParameter(0,"%ja%");
List<Customer> cs = query.list();
for(Customer c:cs){
System.out.println(c);
}
t.commit();
}
- 按参数名字查询
按照参数名称查询时,需要在HQL语句中定义命名参数,命名参数是":"与自定义参数名的组合。代码如下:
@Test
public void paramQueryTest2(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "from Customer where id=:id";
Query query = session.createQuery(hql);
query.setParameter("id",1);
List<Customer> cs = query.list();
for(Customer c:cs){
System.out.println(c);
}
t.commit();
}
分页查询
在实际应用中,批量查询数据时,在单个页面上显示出所有查询结果,这显然是不合理的。这就需要开发人员对查询结果进行分页显示。Hibernate的Query接口中,提供了用于分页显示的查询方法setFirstResult(int firstResult)和setMaxResult(int maxResult)。这两种方法的说明如下。
- setFirstResult(int firstResult):该方法设定从哪个对象开始查询,参数firstResult标识这个对象在查询结果中的索引(索引的初始值为0)
- setMaxResult(int maxResult):该方法设置一次返回多少个对象,通常与setFirstResult(int firstResult)方法结合使用,来限制结果集的范围。缺省时,返回查询结果中的所有对象。
代码如下:
@Test
public void queryPageTest1(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "from Customer";
Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(3);
List<Customer> cs = query.list();
for(Customer c:cs){
System.out.println(c.getId());
}
t.commit();
}