本章介绍了Hibernate的几种主要检索方式:HQL检索方式、QBC检索方式、SQL检索方式。HQL是Hibernate Query Language的缩写,是官方推荐的查询语言。QBC是Query By Criteria的缩写,是Hibernate提供的一个查询接口。Hibernate是一个轻量级的框架,它允许使用原始SQL语句查询数据库。 6.1 HQL基础 HQL是Hiberante官方推荐的Hibernate检索方式,它使用类似SQL的查询语言,以面向对象的方式从数据库中查询。可以使用HQL查询具有继承、多态和关联关系的数据。在检索数据时应优先考虑使用HQL方式。 6.1.1 默认数据库表和数据 在讲解本章时,在没有特殊说明时,用到的数据库均为joblog,也就是在第4章建立的数据库。joblog中添加了3个表:学生表student、课程表course和选课表sc。 学生表student中各字段的结构如图6-1所示,字段的中文含义在Comment列中。
图6-1 学生表的数据结构 学生表student中的数据如图6-2所示,没有特殊说明时,用到的均为这6条记录。 此处仍然使用在第4章建立的HibernateProject项目,但是这里新建了一个包hibernate.ch06,这个包存放本章中的所有代码。在hibernate.ch06包中建立学生表对应的持久化类Student.java,代码如下。
图6-2 学生表中的数据 package hibernate.ch06; //学生类 public class Student { private Integer id; //对象标识符 private Integer sno; //学号 private String sname; //姓名 private String ssex; //性别 private String sdept; //所在系别 private Integer sage; //年龄 private String saddress; //籍贯 …… //省略了所有的get/set访问器 } 课程表course中的各个字段的结构如图6-3所示,字段的中文含义在Comment列中。
图6-3 课程表的结构 课程表中的数据如图6-4所示,如果没有特殊说明,用到的均为这4条记录。
图6-4 课程表的数据 在hibernate.ch06中新建持久化类Course.java类,代码如下。 package hibernate.ch06; //课程类 public class Course { private Integer id; //对象标识符 private Integer cno; //课程号 private String cname; //课程名 private Integer Ccredit; //学分
…… //省略了get/set访问器 } 选修表sc(sc为student-course的缩写)的结构如图6-5所示,字段的中文含义在Comment列中。
图6-5 选修表的结构 选修表中的数据如图6-6所示,没有特殊说明时,用到的均为这5条记录。
图6-6 选修表的数据 在hibernate.ch06中新建持久化类SC.java,SC.java的代码如下。 package hibernate.ch06; //选课类 public class SC implements java.io.Serializable { private Integer id; //id private Integer sno; //学号 private Integer cno; //课程号 private Integer grade; //成绩 public SC() { } …… //省略get/set访问器 } 后面的章节中将用这3个表和3个持久化类进行讲解。 6.1.2 检索类的所有对象 使用HQL语句可以检索出一个类的所有对象,如HQL语句“from Student”表示检索Student类的所有对象。下面的程序检索学生类的所有对象。 Query query=session.createQuery("from Student"); //创建Query对象 List list=query.list(); //执行查询
//以下代码做显示用,以后不再写出来 Iterator it=list.iterator(); while(it.hasNext()){ Student stu=(Student)it.next(); System.out.println("id"+stu.getId()); System.out.println("name"+stu.getSname()); System.out.println("\n"); } session.createQuery()以HQL查询语句为参数,生成一个查询对象。本例中的HQL语句为“from Student”,这是from子句,格式如下。 from 类名 其中,类名可以为类的全限定名,如: from hibernate.ch06.Student Hibernate使用自动引入功能(auto import),会自动寻找需要的类,所以不推荐使用类的全限定名。注意,类名区分大小写,如果写成from student,将会抛出以下异常。 java.lang.NoClassDefFoundError: hibernate/ch06/student (wrong name: hibernate/ch06/Student) HQL关键字不区分大小写,FROM、from和From是一样的。 调用query.list()时,真正开始执行HQL查询语句,并把查询的结果放在List中。 本例中查询的是Student类中的所有属性,如果查询Student类中的某一个或某几个属性,如查询所有学生的姓名和所在系,需要用到属性查询。 6.1.3 检索类的某几个属性 与SQL语句类似,HQL语句可以检索类的某一个或者某几个属性。以下代码查询所有学生的姓名和所在系。 //创建Query对象 Query query=session.createQuery("select Student.sname,Student.sdept from Student"); List list=query.list(); //执行查询 //以下代码显示查询的信息 Iterator it=list.iterator(); while(it.hasNext()){ Object[] stu=(Object[])it.next(); System.out.println("id"+stu[0]); System.out.println("name"+stu[1]); System.out.println("\n"); } 属性查询使用select关键字,属性查询的格式如下。 select 属性1,属性2,… from 类名 属性前可以加上类名加以限定,如: select 属性1,属性2,… from 类名 但一般没有必要。 属性查询区分大小写,上面的代码中如果写成: select SNAME,Sdept from Student 将抛出异常,提示找不到属性SNAME和属性Sdept。 查询结果将只显示查询的属性列。 属性查询的结果,对于用it.next()获得的每条记录,可以存储在Object[]数组中,以便进行存取。 6.1.4 指定别名 在查询时,可以用关键字as指定查询的别名,指定别名可以简化查询,有时必需指定别名才能进行查询。以下代码查询学号中含有4的学生的姓名和所在系。 select s.sname,s.sdept from Student as s wheres.sno like '%4%'from Student s s就是类Student的别名。注意as可以省略,即下面的查询语句和上面的语句是等效的。 select s.sname,s.sdept from Student s where s.sno like '%4%'from Student s 6.1.5 where条件子句 where条件子句跟SQL中的where条件子句类似,它检索符合条件的对象。例如,查询所有所在系别为计算机系的学生: select s.sname,s.sdept from Student s where s.dept=’计算机’ where子句指定查询的条件,其语法和SQL类似。 在where子句中可以指定比较运算符:>、>=、<、<=、<>,其含义分别为大于、大于等于、小于、小于等于、不等于。 查询年龄在22到23岁的学生: from Student s where s.sage>=22 and s.sage<=23 在where子句中指定查询的属性是否为null:is null、is not null,其含义分别表示为空和不为空。 查询所在籍贯为空的学生: from Student s where s.saddress is null 6.1.6 使用distinct过滤掉重复值 使用distinct关键字将去掉结果中的重复值,只检索符合条件的对象。如下面的例子检索学生实例中的不重复的年龄。 Session session=HibernateSessionFactory.currentSession(); //创建Session String hql="select distinct s.sage from Student s"; //HQL查询语句 Query query=session.createQuery(hql); //创建查询 List list=query.list(); //执行查询 检索的结果如下,可见结果中去掉了一个重复的22岁。 20 21 22 23 24
《二》
1.实体的更新和删除: 比如在Hibernate2中,如果我们想将数据库中所有18岁的用户的年龄全部改为20岁,那么我们要首先将年龄在18岁的用户检索出来,然后将他们的年龄修改为20岁,最后调用Session.update()语句进行更新。
在Hibernate3中对这个问题提供了更加灵活和更具效率的解决办法,如下面的代码: 2.分组与排序 (1)检索的结果会返回Customer与Order持久化对象,而且它们会被置于Hibernate的Session缓存之中,并且Session会负责它们在缓存中的唯一性以及与后台数据库数据的同步,只有事务提交后它们才会从缓存中被清除;而语句 (2)返回的是关系数据而并非是持久化对象,因此它们不会占用Hibernate的Session缓存,只要在检索之后应用程序不在访问它们,它们所占用的内存就有可能被JVM的垃圾回收器回收,而且Hibernate不会同步对它们的修改。
3. 参数绑定: |
hibernate--HQL查询语句
最新推荐文章于 2021-01-27 15:03:48 发布