本博文整理Hibernate中SQL查询的标量查询、实体查询以及处理关联和继承
一:标量查询
- public void scalarQuery(){
- Session session=HibernateUtil.currentSession();
- Transaction tx=session.beginTransaction();
- String sql="select stu.* from student_inf as stu";
- List list=session.createSQLQuery(sql)
- .addScalar("name", StandardBasicTypes.STRING)
- .addScalar("student_id", StandardBasicTypes.INTEGER)
- .list();
- for(Object obj:list){
- Object[]row=(Object[]) obj;
- System.out.println(row[0]+"\t"+row[1]);
- }
- System.out.println("------------------------------------------");
- tx.commit();
- HibernateUtil.closeSession();
-
- }
标量查询仅仅是查询了部分数据列,像我们上面的程序仅仅查询了student_inf表中的name和student_id两个数据列的值。在返回结果是一个集合,集合的每一个元素都是一个数组,数组元素是name、student_id两列的值。
上面的addScalar()方法有两个作用:
1:指定查询结果包含哪些数据列,没有被addScalar()选中的数据列不会出现在查询结果中,所以查询结果中只能遍历出来name和student_id两个数据列的值。
2:指定查询结果中数据列的数据类型。
二:实体查询:
实体查询与标量查询不同的是:标量查询只是返回一些标量的结果集,而实体查询返回的是数据表中全部数据列。
实体查询的两个条件:
1:查询返回某个数据表的全部数据列,要选出全部数据列(可以在SQL字符串中使用*来表示返回所有列)
2:该数据表有对应的持久化类映射
步骤:利用SQLQuery提供的addEntity()方法,将查询结果转换成实体。
- public void entityQuery(){
- Session session=HibernateUtil.currentSession();
- Transaction tx=session.beginTransaction();
- String sql="select * from enrolment_inf where year =?1";
- List list=session.createSQLQuery(sql)
- .addEntity(Enrolment.class)
- .setInteger("1", 2005)
- .list();
- for(Object obj:list){
- Enrolment e=(Enrolment) obj;
- System.out.println(e.getStudent().getName()+"\t"+e.getCourse().getName()+"\t\t"+e.getStudent().getId());
- }
- System.out.println("------------------------------------------");
- tx.commit();
- HibernateUtil.closeSession();
- }
上面这个程序就满足了实体查询的两个条件:SQL语句选出了enrolment_inf表中的全部数据列,而且enrolment_inf表被映射到Enrolment持久化类,所以可以通过addEntity()方法将查询结果转化为了Enrolment实体组成的列表。
如果要将查询的结果转化成多个实体,那么SQL字符串应该为不同的数据表指定不同的别名,并调用addEntity("别名",实体类名)方法将不同数据表转化为不同的实体,如下例:
- public void multiEntityQuery(){
- Session session= HibernateUtil.currentSession();
- Transaction tx=session.beginTransaction();
- String sql="select s.*,e.*,c.* "
- +"from student_inf s,enrolment_inf e, course_inf c "
- +"where s.student_id=e.student_id "
- +"and e.course_code=c.course_code";
- List list=session.createSQLQuery(sql)
- .addEntity("s", Student.class)
- .addEntity("e", Enrolment.class)
- .addEntity("c", Course.class)
- .list();
- tx.commit();
- HibernateUtil.closeSession();
- for(Object obj:list){
- Object[]objs=(Object[]) obj;
- Student s=(Student) objs[0];
- Enrolment e=(Enrolment) objs[1];
- Course c=(Course) objs[2];
- System.out.println(s.getName()+"\t"+e.getYear()+"\t"+e.getSemester()+"\t"+c.getName());
- }
- System.out.println("------------------------------------------");
-
- }
上面的程序SQL语句一次返回了student_inf、course_inf、enrolment_inf表中全部数据,并且都有相应的持久化类映射,因为我们可以将查询结果转换为三个实体,我们首先先将不同的表指定不同的别名,然后再调用addEntity("别名",实体类)方法将从不同表查询到的记录转换为相应的实体。最后返回的查询结果列表,列表中的每个元素都是由Student、Enrolment、Course实体组成的数组。
Hibernate也可以将查询结果转换为非持久化实体(也就是普通的类),但是前提是该类为这些数据列提供了相应的get、set方法,
Query接口提供了一个setResultTransformer()方法,该方法接受一个Transformers对象,通过该对象就可以将查询到的结果转换成普通的JavaBean如下:
- public void beanQuery(){
- Session session =HibernateUtil.currentSession();
- Transaction tx=session.beginTransaction();
- String sql="select s.name stuName, s.student_id stuId,c.name courseName "
- +"from student_inf s,enrolment_inf e,course_inf c "
- +"where s.student_id =e.student_id "
- +"and e.course_code=c.course_code";
- List list = session.createSQLQuery(sql)
-
- .setResultTransformer(Transformers
- .aliasToBean(StudentCourse.class))
- .list();
-
- tx.commit();
- HibernateUtil.closeSession();
-
- for (Object ele : list)
- {
-
- StudentCourse sc = (StudentCourse)ele;
- System.out.println(sc.getStuName() + "\t"+sc.getStuId()+"\t"
- + sc.getCourseName());
- }
- System.out.println("------------------------------------------");
以下是StudentCourse类,需要提供上面查询的stuName、stuId、courseName的set、get方法
- public class StudentCourse {
- private String stuName;
- private Integer stuId;
- private String courseName;
- public String getStuName() {
- return stuName;
- }