在上1篇文章(《千山万水之Hibernate(3)――基本映照 》)中,我们介绍了怎样通过Hibernate进行最基本的单实体映照和Hibernate设计的1些基本原理,本篇文章将介绍关联映照中的多对1映照是如何实现的。
我们拿学生和班级为示例,学生属于某1个班级,而且多个学生是有可能属于同1个班级的,相应的实体关系图为:
Class的映照文件向上1篇我们介绍到的基本映照文件那样编写即可以,而对Student实体,我们需要从Student中得出对应班级,而Student与Class正是多对1的体现,因此需要在Student中加入many-to-one标签,以表达出这类关联关系:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping>
<class name="com.tgb.hibernate.Student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<many-to-one name="classes" column="classId"></many-to-one>
</class>
</hibernate-mapping>
为了示例方便,首先我们编写1个简单的Hibernate操作工具类,封装SessionFactory创建、Session的打开与关闭:
public class HibernateTool {
private static SessionFactory factory;
static{
try{
Configuration cfg = new Configuration().configure();
factory=cfg.buildSessionFactory();
}catch(Exception e){
e.printStackTrace();
}
}
public static Session getSession(){
return factory.openSession();
}
public static void closeSession(Session session){
if(session != null){
if(session.isOpen()){
session.close();
}
}
}
public static SessionFactory getSessionFactory(){
return factory;
}
}
1.调用session的Load方法,得出Student对象的级联班级对象Classes(这也是Hibernate为我们提供的1大好处):
public void testLoad(){
Session session = null;
try{
session = HibernateTool.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 2);
System.out.println("student.name=" + student.getName());
System.out.println("student.class.name=" + user.getClasses().getName());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateTool.closeSession(session);
}
}
2.当保存数据时,我们已知道关联有Transient对象的Persistent状态的对象不能直接保存至数据库,由于在清算缓存时,不能得到关联对象的标识符,因此,我们有两种解决方案,在将Student对象进行保存前,先将关联的Classes对象保存,使其保持在Persistent状态,则Student保存成功,另外1种便是设置级联保存:
这样在保存Student对象时,也会将级联的班级对象进行保存:
public void testSave(){
Session session = null;
try{
session = HibernateTool.getSession();
session.beginTransaction();
Class classes = new Class();
classes.setName("LFSFXY-TGB");
Student student = new Student();
student.setName("张3");
student.setClasses(classes);
session.save(student);
System.out.println("student.name=" + student.getName());
System.out.println("student.classes.name=" + student.getClasses().getName());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateTool.closeSession(session);
}
}
通过上面的介绍相信你1定知道了Hibernate中的多对1究竟是怎样1回事,通过示例我们也体会到了对象关联给我们带来的好处:级联查询出实体,舍弃了我们之前繁琐的SQL语句操作。也通过级联属性cascade简单了解了级联保存的操作。
只有通过不断的练习实践、总结才能1步步到达熟练利用的程度,继续加油!