Hibernate映射List

来源:互联网 发布:python 循环 编辑:程序博客网 时间:2024/06/05 11:48

hibernate映射List,其中List中的元素可以是String、Long、Date等可以直接映射到字段上的Java类型,较为复杂的就是List中的元素的类型为我们自定义的类型。

以Team类为例:

(1)映射的List中的元素为我们自定义的Student类型:

持久化类Team:

[java] view plain copy
print?
  1. package bean;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class Team {  
  6.     private long id;  
  7.     private String name;  
  8.     private List<Student> students;  
  9.         //省略setXxx()、getXxx()方法  
  10. }  
持久化类Student:

[java] view plain copy
print?
  1. package bean;  
  2.   
  3. public class Student {  
  4.     private long id;  
  5.     private long cardID;  
  6.     private String name;  
  7.     private int age;  
  8.     private Team team;  
  9.         //省略setXxx()、getXxx()方法  
  10. }  
对象关系映射文件Team.hbm.xml(并将其加入到主配置文件中<mapping resource="Team.hbm.xml"/>)
[html] view plain copy
print?
  1. <hibernate-mapping>  
  2.     <class name="bean.Team" table="team">  
  3.         <id name="id" column="id" type="long">  
  4.             <generator class="increment"></generator>  
  5.         </id>  
  6.         <property name="name" column="name" type="string"></property>  
  7.         <list name="students" cascade="all">  
  8.             <key column="team_id"></key>  
  9.             <index column="index_"></index><!-- 注意index是数据库中的关键字要避免与其冲突,此处index_对应元素在List中的索引 -->  
  10.             <one-to-many class="bean.Student"/>  
  11.         </list>  
  12.     </class>  
  13. </hibernate-mapping>  
对象关系映射文件Student.hbm.xml(并将其加入到主配置文件中<mapping resource="Student.hbm.xml"/>)
[html] view plain copy
print?
  1. <hibernate-mapping>  
  2.     <class name="bean.Student" table="students">  
  3.         <id name="id" column="id" type="long">  
  4.             <generator class="increment"></generator>  
  5.         </id>  
  6.         <property name="name" column="name" type="string"></property>  
  7.         <property name="age" column="age" type="int"></property>  
  8.         <property name="cardID" column="cardID" type="long"></property>  
  9.         <many-to-one name="team" class="bean.Team" column="team_id" cascade="none"></many-to-one>  
  10.     </class>  
  11. </hibernate-mapping>  
说明:

(1)Team和Student为双向关联关系,特别需要注意延迟加载lazy属性、cascade级联属性、inverse等属性的设置。

(2)<list>中的<index>子元素指定元素在List中的索引字段,不必在Student类中加入这一属性。students表中的team_id字段参照team表中的id字段,两表的结构如下:

级联保存Team对象:

[java] view plain copy
print?
  1. tx=session.beginTransaction();  
  2. Team t1=new Team();  
  3. t1.setName("team1");  
  4. t1.setStudents(new ArrayList<Student>());  
  5. t1.getStudents().add(new Student(1001L,23,"zhangsan"));  
  6. t1.getStudents().add(new Student(1002L,23,"lisi"));  
  7. t1.getStudents().add(new Student(1003L,23,"wangwu"));  
  8.   
  9. session.save(t1);  
  10. tx.commit();  
此时控制台输出的SQL语句为:

[sql] view plain copy
print?
  1. Hibernate: select max(id) from team  
  2. Hibernate: select max(id) from students  
  3. Hibernate: insert into team (name, id) values (?, ?)  
  4. Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)  
  5. Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)  
  6. Hibernate: insert into students (name, age, cardID, team_id, id) values (?, ?, ?, ?, ?)  
  7. Hibernate: update students set team_id=?, index_=? where id=?//可以看出Hibernate先保存对象属性的默认值,然后再更新对象  
  8. Hibernate: update students set team_id=?, index_=? where id=?  
  9. Hibernate: update students set team_id=?, index_=? where id=?  

删除对象:

[java] view plain copy
print?
  1. Team t=(Team)session.get(Team.class,2L);  
  2. session.delete(t);  

若将cascade设为save-update即不具有级联删除的级联级别,控制台输出SQL语句如下:

[sql] view plain copy
print?
  1. Hibernate: select team0_.id as id0_0_, team0_.name as name0_0_ from team team0_ where team0_.id=?  
  2. Hibernate: update students set team_id=null, index_=null where team_id=?  
  3. Hibernate: delete from team where id=?  
可知并没有将students表中对应的记录删除,只是将相关字段设为了NULL,students表内容如下:

可将cascade改为all或其他值实现级联删除。

(2)至于较为简单的映射List的情况,以List中的元素为String类型为例,修改如下

(1).修改Team的students属性类型为List<String>,并修改其set、get方法;

(2).修改Team.hbm.xml映射文件:

[html] view plain copy
print?
  1. <list name="students" cascade="save-update" table="students">  
  2.     <key column="team_id"></key>  
  3.     <index column="index_"></index><!-- 注意index是数据库中的关键字 -->  
  4.     <!-- <one-to-many class="bean.Student"/> -->  
  5.     <element column="name" type="string"></element>  
  6. </list>  
说明:

(1)<element>对应于List中的元素,即学生的姓名。

(2)students表的主键为(team_id,index_)组合主键(这与映射Map<Long,String>中表的结构很相似)。两表结构如下:


保存Team对象:

[java] view plain copy
print?
  1. tx=session.beginTransaction();  
  2. Team t1=new Team();  
  3. t1.setName("team1");  
  4. t1.setStudents(new ArrayList<String>());  
  5. t1.getStudents().add("zhangsan");  
  6. t1.getStudents().add("lisi");  
  7. t1.getStudents().add("wangwu");  
  8.   
  9. session.save(t1);  

在保存时遇到了一个异常:Caused by: java.sql.SQLException: Field 'id' doesn't have a default value,解决办法:注释掉hibernate.cfg.xml文件中的Student映射:

[html] view plain copy
print?
  1. <!-- <mapping resource="Student.hbm.xml"/> --> ,因为与原先的students表的结构不同(原表中有id主键),所以需删除原students表。  

删除Team对象:

若将cascade设为save-update(即没有级联删除的级别)则依然会将students表中的对应记录删除,而不是将某些字段设为NULL。(与映射Set<String>相似)


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