Hibernate映射Bag

来源:互联网 发布:狸窝 mac 编辑:程序博客网 时间:2024/06/08 09:51
Bag(结合了List与Set),可以重复且没有顺序的一种集合,是Hibernate提供的。HIbernate使用jdk的List模拟Bag。其配置与Hibernate映射List时基本相同。

以Team、Student为例:

持久化类Team(与映射List<Student>时相同):

package bean;import java.util.List;public class Team {private long id;private String name;private List<Student> students;        //省略get、set方法}

持久化类Student(与映射List<Student>时相同):

package bean;public class Student {private long id;private long cardID;private String name;private int age;private Team team;       //省略get、set方法}

对象关系映射文件Team.hbm.xml:

<hibernate-mapping><class name="bean.Team" table="team"><id name="id" column="id" type="long"><generator class="increment"></generator></id><property name="name" column="name" type="string"></property><bag name="students" cascade="all" table="students"><key column="team_id"></key> <one-to-many class="bean.Student"/> </bag></class></hibernate-mapping>

Student.hbm.xml(与映射List<Student>时相同):

<hibernate-mapping><class name="bean.Student" table="students"><id name="id" column="id" type="long"><generator class="increment"></generator></id><property name="name" column="name" type="string"></property><property name="age" column="age" type="int"></property><property name="cardID" column="cardID" type="long"></property>        <many-to-one name="team" class="bean.Team" column="team_id" cascade="none"></many-to-one></class></hibernate-mapping>

并将它们加入到主配置文件中:

    <mapping resource="Team.hbm.xml"/>    <mapping resource="Student.hbm.xml"/> 
说明:

Hibernate依然将Team的List中的元素放置到另一张表中(此处即students表),与映射List不同的是<bag>中不需要指定index索引(因为Bag中的元素是可重复并且无续的),team表和students表结构如下:

级联保存Team对象:

              tx=session.beginTransaction();              Team t1=new Team();              t1.setName("team1");              t1.setStudents(new ArrayList<Student>());              t1.getStudents().add(new Student(1001L,23,"zhangsan"));              t1.getStudents().add(new Student(1002L,23,"lisi"));              t1.getStudents().add(new Student(1001L,23,"zhangsan"));                         session.save(t1);              tx.commit();
此时输出的SQL语句为:

Hibernate: select max(id) from teamHibernate: select max(id) from studentsHibernate: insert into team (name, id) values (?, ?)Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)Hibernate: update students set team_id=? where id=?Hibernate: update students set team_id=? where id=?Hibernate: update students set team_id=? where id=?
可以看出执行流程是先取一个默认值(实际为NULL)给team_id向students表中插入一条记录,然后再执行update语句更新students表中的对应记录的team_id字段值。

若将Team.hbm.xml中<bag>元素的inverse属性值改为true:

<bag name="students" cascade="save-update" table="students" inverse="true"><!--指定由students表维持两表之间的关联关系-->
然后再执行上述保存Team对象的语句,此时输出的SQL语句为:

Hibernate: select max(id) from teamHibernate: select max(id) from studentsHibernate: insert into team (name, id) values (?, ?)Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)
对比可知,并没有执行上述的update语句,原因就在于是students表维持两表之间的关联关系而不再是Team表,通过对比以下students表中的前三条记录和后三条记录就可以理解inverse的作用,并且Bag存放的元素是可以重复及无续的:


转载请注明出处:http://blog.csdn.net/jialinqiang/article/details/8688481

原创粉丝点击