本博文整理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) // 指定将查询的记录行转换成StudentCourse对象 .setResultTransformer(Transformers .aliasToBean(StudentCourse.class)) .list(); // 提交事务,关闭Session tx.commit(); HibernateUtil.closeSession(); // 因为数据已经全部被选出,故程序可以遍历列表中的数据 for (Object ele : list) { // 每个集合元素都是StudentCourse对象 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; } public void setStuName(String stuName) { this.stuName = stuName; } public String getCourseName() { return courseName; } public void setCourseName(String courName) { this.courseName = courName; } public Integer getStuId() { return stuId; } public void setStuId(Integer stuId) { this.stuId = stuId; } }