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 team Hibernate: select max(id) from students Hibernate: 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 team Hibernate: select max(id) from students Hibernate: 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