一、一对多的关系映射
建立一对多关系关系的表的原则是将一的一方的主键加入到多的一方的表作为外键。这里以员工和部门为例子来演示。以前不用hibernate时建立pojo类要在员工类Emp中加入一个属性,即部门编号deptid.使用hibernate则不同了,需要在“一”的一方类中加入一个set集合,里面存放“多”的一方的对象。而在“多”的一方的类中需要加入一个“一”方的对象。也就是说在Dept类中需要加入一个set集合,存放Emp对象,因为一个部门里面对应多个员工,所以用一个集合来表示。而每一个员工只能属于一个部门,所以员工类Emp里面需要加入一个Depe类对象,表示所属部门。部门类和员工类的代码如下
1 public class Dept implements Serializable { 2 private int deptId; 3 private String deptName; 4 private Set<Emp> emps = new HashSet<Emp>(); 5 public int getDeptId() { 6 return deptId; 7 } 8 public void setDeptId(int deptId) { 9 this.deptId = deptId; 10 } 11 public String getDeptName() { 12 return deptName; 13 } 14 public void setDeptName(String deptName) { 15 this.deptName = deptName; 16 } 17 public Set<Emp> getEmps() { 18 return emps; 19 } 20 public void setEmps(Set<Emp> emps) { 21 this.emps = emps; 22 } 23 }
1 public class Emp implements Serializable{ 2 private int empNo; 3 private String empName; 4 private Date empBirthday; 5 private Dept dept; 6 public int getEmpNo() { 7 return empNo; 8 } 9 public void setEmpNo(int empNo) { 10 this.empNo = empNo; 11 } 12 public String getEmpName() { 13 return empName; 14 } 15 public void setEmpName(String empName) { 16 this.empName = empName; 17 } 18 public Date getEmpBirthday() { 19 return empBirthday; 20 } 21 public void setEmpBirthday(Date empBirthday) { 22 this.empBirthday = empBirthday; 23 } 24 public Dept getDept() { 25 return dept; 26 } 27 public void setDept(Dept dept) { 28 this.dept = dept; 29 } 30 31 }
写完pojo类后就要配置这两个类和表之间的映射关系了,代码如下:
1.Dept.hbm.xml
1 <hibernate-mapping> 2 <!-- 表和类之间的映射 --> 3 <class name="com.pojo.Dept" table="dept"> 4 <!-- 主键映射 --> 5 <id name="deptId" column="deptId"> 6 <generator class="native"></generator> 7 </id> 8 <!-- 属性映射 --> 9 <property name="deptName" column="deptName" length="50"></property> 10 <!-- 表之间关系映射 --> 11 <set name="emps" cascade="save-update,delete"> 12 <key column="deptId"></key> 13 <one-to-many class="com.pojo.Emp"/> 14 </set> 15 </class> 16 </hibernate-mapping>
这里面配置了一个set,里面的name="emps"表示在Dept类里的属性emps,它是一个集合,存放Emp对象的。cascade="save-update,delete"指明可以级联删除,级联插入数据。cascade有四个值:all、save-update、delete、none,默认就是none,表示不能级联操作。<one-to-many class="com.pojo.Emp"/>表示Dept与Emp是一对多的关系,他们是以deptId建立关系的,即deptId是Emp的外键。
2.Emp.hbm.xml
1 <hibernate-mapping> 2 <!-- 表和类之间的映射 --> 3 <class name="com.pojo.Emp" table="emp"> 4 <!-- 主键映射 --> 5 <id name="empNo" column="empNo"> 6 <generator class="native"></generator> 7 </id> 8 <!-- 属性映射 --> 9 <property name="empName" column="empName" length="50"></property> 10 <property name="empBirthday" column="empBirthday"></property> 11 <!-- 表之间关系映射 --> 12 <many-to-one name="dept" column="deptId"></many-to-one> 13 </class> 14 </hibernate-mapping>
这里加了<many-to-one></many-to-one>表示Emp与Dept是多对一的关系,name="dept"表示在Emp类里面有一个属性是Dept对对象dept,column="deptId"表示 它们之间是用deptId建立联系的。
下面是级联插入数据的代码:
1 package com.test; 2 3 import java.util.Date; 4 5 import org.hibernate.Session; 6 import org.hibernate.Transaction; 7 8 import com.pojo.Dept; 9 import com.pojo.Emp; 10 import com.util.DBUtil; 11 12 public class 级联插入数据 { 13 14 /** 15 * @param args 16 */ 17 public static void main(String[] args) { 18 //获得session 19 Session session = DBUtil.getSession(); 20 //新建一个dept 21 Dept dept = new Dept(); 22 dept.setDeptName("吃饭部"); 23 24 //新建emp 25 Emp e1 = new Emp(); 26 e1.setEmpName("李白"); 27 e1.setEmpBirthday(new Date()); 28 29 Emp e2 = new Emp(); 30 e2.setEmpName("王维"); 31 e2.setEmpBirthday(new Date()); 32 33 dept.getEmps().add(e1); 34 dept.getEmps().add(e2); 35 36 Transaction tr = session.beginTransaction(); 37 try { 38 session.save(dept); 39 tr.commit(); 40 } catch (Exception e) { 41 tr.rollback(); 42 }finally{ 43 session.close(); 44 } 45 } 46 47 }
先建立一个dept对象,然后建立两个emp对象,然后把这两个emp对象加入到dept对象的集合里面,然后保存dept。级联插入只要操作父表,就可以操作子表。前提是要在前面那个cascade="save-update"必须写。