图6-9 本节中所用的表sc中的内容 6.4.3 修改持久化类
Student对象和Course对象之间是多对多的关系。此处使用的是单向关联,仅仅建立从Student到Course的单向关联。如图6-10所示,仅有Student到Course的单向关联。
图6-10 Student到Course类的单向关联
为了建立Student到Course的单向关联关系,在Student.java中新加一个属性course。course属性是Set型的,可以在这个属性中加入多个Course对象,建立起关联关系。下面是加入course属性后的源代码,粗体部分为加入的代码。 package hibernate.ch06; import java.util.HashSet; import java.util.Set;
public class Student implements java.io.Serializable { private Integer id; //ID private Integer sno; //学号 private String sname; //姓名 private String ssex; //性别 private String sdept; //系部 private Integer sage; //年龄 private String saddress; //住址
private Set course=new HashSet(); //所选课程 public Student() { }
//此处省略其他的构造方法
//此处省略getter/setter访问器 //course属性的get访问器 public Set getCourse() { return course; }
//course属性的set访问器
public void setCourse(Set course) { this.course = course; } }
持久化类Course.java和SC.java无需修改。 6.4.4 在映射文件中加入关联信息
在Student.hbm.xml映射配置文件中,加入Student到Course的映射信息。关于如何映射关联关系,将在第8章讲解,读者可暂时按照下面的设置,具体含义等阅读完第八章便可理解。具体代码如下。
完整的配置文件Student.hbm.xml如下所示。 6.4.5 左外连接 左外连接(Left Outer Join)查询出左表对应的复合条件的所有记录,如查询李晓梅同学的选课信息。下面是类HQLLeftOuterJoinQuery的源代码。 package hibernate.ch06; import hibernate.HibernateSessionFactory; import java.util.Iterator; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; public class HQLLeftOuterJoinQuery { public static void main(String[] args) { Session session=HibernateSessionFactory.currentSession(); //HQL查询语句 String hql=\李晓梅'\ Query query=session.createQuery(hql); //创建查询 List list=query.list(); //执行查询 Iterator it=list.iterator(); while(it.hasNext()){ Object[] obj=(Object[])it.next(); Student stu=(Student)obj[0]; Course course=(Course)obj[1]; System.out.println(\学生信息及其选课信息******************\ if(course!=null){ System.out.println(stu.getSno()+\ \课程:\ }else{ System.out.println(stu.getSno()+\ }; } } } 如果只用单表查询,只能从student表中查询出李晓梅的个人信息,而无法知道她的选课信息,因为选课信息存储在中间表sc中。HQL语句from Student s left join s.course c where s.sname='李晓梅'检索出了李晓梅的选课信息。 在HQL中使用left outer join关键字进行左外连接,outer关键字可以省略。 s.course是Student对象中的一个属性,用来存储Student对象的选课信息。在执行查询时,将根据Student.hbm.xml中的配置生成SQL语句,并检索信息。 查询的结果返回一个Object[]数组,数组的第0个元素是Student对象,第1个元素是与Object[0]中对应的学生所选课的Course对象。 HQLLeftOuterJoinQuery类在执行过程中生成的左外连接的SQL语句如下。 Hibernate: select student0_.id as id1_0_, course2_.id as id4_1_, student0_.Sno as Sno1_0_, student0_.Sname as Sname1_0_, student0_.Sdept as Sdept1_0_, student0_.Sage as Sage1_0_, student0_.Ssex as Ssex1_0_, student0_.Saddress as Saddress1_0_, course2_.Cno as Cno4_1_, course2_.Cname as Cname4_1_, course2_.Ccredit as Ccredit4_1_ from joblog.student student0_ left outer join sc course1_ on student0_.id=course1_.sno left outer join joblog.course course2_ on course1_.cno=course2_.id where student0_.Sname='李晓梅' Hibernate: select course0_.sno as sno1_, course0_.cno as cno1_, course1_.id as id4_0_, course1_.Cno as Cno4_0_, course1_.Cname as Cname4_0_, course1_.Ccredit as Ccredit4_0_ from sc course0_ left outer join joblog.course course1_ on course0_.cno=course1_.id where course0_.sno=? 程序的查询结果如下。 *********学生信息及其选课信息****************** 20040001 李晓梅 课程:数据库 *********学生信息及其选课信息****************** 20040001 李晓梅 课程:操作系统 使用如下语句将只返回Student对象。 select s from Student s left join s.course c where s.sname='李晓梅' 如下是只返回Student对象的部分代码。 Session session=HibernateSessionFactory.currentSession(); //HQL查询语句 String hql=\李晓梅'\ Query query=session.createQuery(hql); //创建查询 List list=query.list(); //执行查询 Iterator it=list.iterator(); while(it.hasNext()){ Student stu=(Student)it.next(); System.out.println(\学生信息及其选课信息******************\ System.out.println(stu.getSno()+\ } 6.4.6 左外抓取连接 左外抓取连接指定在Hibernate检索数据时,采用抓取的方式,直接将数据加载到与Student对象关联的course属性中。下面是左外抓取连接的程序。 //HQL查询语句 String hql=\李晓梅'\ Query query=session.createQuery(hql); //创建查询