Hibernate collection 映射:
在使用set,list,map和bag标签来表示集合的时候有几个属性可以设置:
1. cascade:级联属性,用于表示在对一个实体进行修改的时候修改与他关联的实体。cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan",这个是在我们配置集合在one的一方中的set或list等中的配置,如果在many的一方的话直接在many-to-one标签中进行设置即可。
2. inverse:表示控制关系是否反转,这个属性只在双向映射的时候使用。表示谁是主方,来维护双方的关系。这里举一个例子说明二者:
public class Student {
private int studentId;
private String name;
private TheClass includeClass;
//省略set,get方法
}
public class TheClass {
private int id;
private String name;
private List<Student> stuList;
//省略set,get方法
}
然后看hbm配置文件:
<class name="Student" table="student">
<id name="studentId" column="id">
</id>
<property name="name"></property>
<many-to-one name="includeClass" class="com.pack.dao.TheClass" column="classid" cascade="all"/>
</class>
数据库中student表中有一个外键classid关联到class表中的id;我们在多的一方直接配置一个<many-to-one>这里指定关联使用的column是外键classid.然后这里也指定了cascade=all,这是说如果我们在保存student对象的时候,他也会将与之关联的theClass对象保存进去,但是在保存之前他应该会先查询一下。以防止保存失败。然后这里也指定了 与之关联的class为TheClass
<class name="TheClass" table="class">
<id name="id" column="id"></id>
<property name="name"></property>
<list name="stuList" cascade="all" inverse="false">
<key column="classid"/>
<list-index column="studentId"></list-index>
<one-to-many class="Student"/>
</list>
</class>
看到这里设置了一个list用于指定TheClass类中的stuList属性。同时指定这个关联的关系。
首先,list中有一key,这个key是说明list中的对象即Student对象与TheClass对象关联的外键,这里用我们的外键classId 即可。然后还有一个list-index因为list是有序的,和set不同,set的话没有与这个相关的属性。这个list-index是用于指定一个索引字段,我在这里指定的是studentId,就是Student表的primarykey。因为它是唯一的,可以作为索引字段。在这个字段的设置上我犯了一个错误,起始我的Student类中的studentId直接就是id。所以我这个字段指定的就是id,但是这样的话我在保存一个TheClass对象的时候他无法帮我将list中存储的Student对象都保存一下。而只是由于inverse=false;所以他只是根据List中保存的对象的studentId来执行以下update student set name=? classid=? Where id=?;但是我的cascade=‘all’基本上没有起作用。因为他没有帮我把与theClass对象关联的student对象保存到数据库中,我觉得他是混淆了id。因为theClass对象中也有一个id属性。待我把id改成studentID,然后修改xml中的设置之后就会帮我插入与之关联的对象。
下面是有关操作的代码:
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
TheClass theClass = new TheClass();
theClass.setId(13);
theClass.setName("newAddClass13");
List<Student> stuSet = new LinkedList<Student>();
Student tempStu = new Student();
tempStu.setStudentId(121);
tempStu.setName("stu121");
tempStu.setIncludeClass(theClass);
stuSet.add(tempStu);
theClass.setStuList(stuSet);
//session.save(tempStu);
session.save(theClass);
保存theClass对象。
session.getTransaction().commit();
session.close();
再说说inverse。可以在list标签中设置这个inverse=false/true对象,如果为false表示由该one的一方来维护关系。当我们更新我们的one的一方的实体的时候,他会更新目前他的list属性中存在的与之关联的对象。而如果我们保存many一方的实体的实体,他却不会根据目前与之实体关联的对象来更新one一方的对象。反之亦然。但是建议将之设置为true。表示将维护关系的任务交给多的一方,这是hibernate官方推荐的。
在使用set,list,map和bag标签来表示集合的时候有几个属性可以设置:
1. cascade:级联属性,用于表示在对一个实体进行修改的时候修改与他关联的实体。cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan",这个是在我们配置集合在one的一方中的set或list等中的配置,如果在many的一方的话直接在many-to-one标签中进行设置即可。
2. inverse:表示控制关系是否反转,这个属性只在双向映射的时候使用。表示谁是主方,来维护双方的关系。这里举一个例子说明二者:
public class Student {
private int studentId;
private String name;
private TheClass includeClass;
//省略set,get方法
}
public class TheClass {
private int id;
private String name;
private List<Student> stuList;
//省略set,get方法
}
然后看hbm配置文件:
<class name="Student" table="student">
<id name="studentId" column="id">
</id>
<property name="name"></property>
<many-to-one name="includeClass" class="com.pack.dao.TheClass" column="classid" cascade="all"/>
</class>
数据库中student表中有一个外键classid关联到class表中的id;我们在多的一方直接配置一个<many-to-one>这里指定关联使用的column是外键classid.然后这里也指定了cascade=all,这是说如果我们在保存student对象的时候,他也会将与之关联的theClass对象保存进去,但是在保存之前他应该会先查询一下。以防止保存失败。然后这里也指定了 与之关联的class为TheClass
<class name="TheClass" table="class">
<id name="id" column="id"></id>
<property name="name"></property>
<list name="stuList" cascade="all" inverse="false">
<key column="classid"/>
<list-index column="studentId"></list-index>
<one-to-many class="Student"/>
</list>
</class>
看到这里设置了一个list用于指定TheClass类中的stuList属性。同时指定这个关联的关系。
首先,list中有一key,这个key是说明list中的对象即Student对象与TheClass对象关联的外键,这里用我们的外键classId 即可。然后还有一个list-index因为list是有序的,和set不同,set的话没有与这个相关的属性。这个list-index是用于指定一个索引字段,我在这里指定的是studentId,就是Student表的primarykey。因为它是唯一的,可以作为索引字段。在这个字段的设置上我犯了一个错误,起始我的Student类中的studentId直接就是id。所以我这个字段指定的就是id,但是这样的话我在保存一个TheClass对象的时候他无法帮我将list中存储的Student对象都保存一下。而只是由于inverse=false;所以他只是根据List中保存的对象的studentId来执行以下update student set name=? classid=? Where id=?;但是我的cascade=‘all’基本上没有起作用。因为他没有帮我把与theClass对象关联的student对象保存到数据库中,我觉得他是混淆了id。因为theClass对象中也有一个id属性。待我把id改成studentID,然后修改xml中的设置之后就会帮我插入与之关联的对象。
下面是有关操作的代码:
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
TheClass theClass = new TheClass();
theClass.setId(13);
theClass.setName("newAddClass13");
List<Student> stuSet = new LinkedList<Student>();
Student tempStu = new Student();
tempStu.setStudentId(121);
tempStu.setName("stu121");
tempStu.setIncludeClass(theClass);
stuSet.add(tempStu);
theClass.setStuList(stuSet);
//session.save(tempStu);
session.save(theClass);
保存theClass对象。
session.getTransaction().commit();
session.close();
再说说inverse。可以在list标签中设置这个inverse=false/true对象,如果为false表示由该one的一方来维护关系。当我们更新我们的one的一方的实体的时候,他会更新目前他的list属性中存在的与之关联的对象。而如果我们保存many一方的实体的实体,他却不会根据目前与之实体关联的对象来更新one一方的对象。反之亦然。但是建议将之设置为true。表示将维护关系的任务交给多的一方,这是hibernate官方推荐的。