Hibernate关联关系配置(多对一,一对多)
第一种关联关系:一对多(多对一)
"一对多"是最普遍的映射关系,简单来讲就如员工与部门的关系。
一对多:从部门的角度来说一个部门有多个员工,即为一对多。
多对一:从员工的角度来说多个员工对应一个部门,即多对一。
多对一关系单向在hbm文件中的配置信息:
Emp.hbm.xml中:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package:要映射的对象所在的包(可选,如果不指定,此文件下所有的类都要指定全路径)
auto-import 默认为true,在写HQL的时候自动导入包名
如果指定为false,在写HQL的时候必须要写上类的全名-->
<hibernate-mapping package="cn.xsy.entity.day_manytoone"> <class name="Emp" table="Emp"> <id name="empno" column="empno"> <generator class="native"></generator> </id> <many-to-one name="dept" class="Dept" column="deptno"></many-to-one> <property name="empname"></property> </class> </hibernate-mapping>
这里加了<many-to-one></many-to-one>表示Emp与Dept是多对一的关系,name="dept"表示在Emp类里面有一个属性是Dept对象dept,column="deptno"表示 它们之间是用deptno建立联系的。
Demp.hbm.xml中:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package:要映射的对象所在的包(可选,如果不指定,此文件下所有的类都要指定全路径)
auto-import 默认为true,在写HQL的时候自动导入包名
如果指定为false,在写HQL的时候必须要写上类的全名-->
<hibernate-mapping package="cn.xsy.entity.day_manytoone"> <class name="Dept" table="Dept"> <id name="deptno" column="deptno"> <generator class="native"></generator> </id> <property name="deptname"></property> </class> </hibernate-mapping>
测试类中:
1 package day01; 2 3 import cn.xsy.entity.day01.Student; 4 import cn.xsy.entity.day_manytoone.Emp; 5 import org.hibernate.Session; 6 import org.hibernate.SessionFactory; 7 import org.hibernate.cfg.Configuration; 8 import org.junit.Test; 9 10 /** 11 * Created by Administrator on 2017/12/28. 12 */ 13 public class Test20171228_manytoone { 14 @Test 15 public void t1() { 16 //COnfiguration 17 Configuration cfg = new Configuration().configure("hibernate.cfgmanyandone.xml"); 18 //1.SessionFactory 19 SessionFactory factory = cfg.buildSessionFactory(); 20 //2.Session 21 Session session = factory.openSession();//从连接池中随机取出连接 22 23 24 //3.操作 25 Emp emp = session.get(Emp.class, 1); 26 27 System.out.println(emp.getEmpname()); 28 29 System.out.println(emp.getDept().getDeptname()); 30 31 } 32 }
效果:
建立一对多关系双向的表的原则是将一的一方的主键加入到多的一方的表作为外键。这里以员工和部门为例子来演示。在员工类Emp中加入一个属性,即部门编号depno.使用hibernate则不同了,需要在“一”的一方类中加入一个set集合,里面存放“多”的一方的对象。而在“多”的一方的类中需要加入一个“一”方的对象。也就是说在Dept类中需要加入一个set集合,存放Emp对象,因为一个部门里面对应多个员工,所以用一个集合来表示。而每一个员工只能属于一个部门,所以员工类Emp里面需要加入一个Depe类对象,表示所属部门。部门类和员工类的代码如下:
Dept.hbm.xml中:
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <!--根节点-->
<!-- package:要映射的对象所在的包(可选,如果不指定,此文件下所有的类都要指定全路径)
auto-import 默认为true,在写HQL的时候自动导入包名
如果指定为false,在写HQL的时候必须要写上类的全名-->
6 <hibernate-mapping package="cn.xsy.entity.day_onetomanydouble"> 7 <class name="Dept" table="Dept" schema="y2166"> 8 <id name="deptno" column="deptno"> 9 <generator class="native"></generator> 10 </id> 11 <property name="deptname" /> 12 <!--一对多 1个部门 多个员工--> 13 <!--inverse:true:放弃维护关系:不去干预底层集合数据改变生成sql的策略--> 14 <set name="emps" cascade="save-update,delete" inverse="false" order-by="empno desc"> 15 <key column="deptno"></key> 16 <one-to-many class="Emp"></one-to-many> 17 </set> 18 </class> 19 </hibernate-mapping>
这里面配置了一个set,里面的name="emps"表示在Dept类里的属性emps,它是一个集合,存放Emp对象的。cascade="save-update,delete"指明可以级联删除,级联插入数据。cascade有四个值:all、save-update、delete、none,默认就是none,表示不能级联操作。<one-to-many class="Emp"/>表示Dept与Emp是一对多的关系,他们是以deptno建立关系的,即deptno是Emp的外键。
Emp.hbm.xml中:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package:要映射的对象所在的包(可选,如果不指定,此文件下所有的类都要指定全路径)
auto-import 默认为true,在写HQL的时候自动导入包名
如果指定为false,在写HQL的时候必须要写上类的全名-->
<hibernate-mapping package="cn.xsy.entity.day_onetomanydouble"> <class name="Emp" table="Emp" schema="y2166"> <id name="empno" column="empno"> <generator class="native"></generator> </id> <property name="empname" /> <!--多对一: emp多的一方 dept一的一方--> <many-to-one name="dept" class="Dept" column="deptno"></many-to-one> </class> </hibernate-mapping>
这里加了<many-to-one></many-to-one>表示Emp与Dept是多对一的关系,name="dept"表示在Emp类里面有一个属性是Dept对象dept,column="deptno"表示 它们之间是用deptno建立联系的。
测试类:
1 package day01; 2 3 4 import cn.xsy.entity.day_onetomanydouble.Dept; 5 import cn.xsy.entity.day_onetomanydouble.Emp; 6 import cn.xsy.util.HibernateUtil; 7 import org.hibernate.Query; 8 import org.hibernate.Session; 9 import org.hibernate.Transaction; 10 import org.junit.Test; 11 12 import java.util.List; 13 14 /** 15 * Created by Happy on 2017-12-24. 16 */ 17 public class Test20171228_onetomanydouble { 18 19 //一对多双向关联 20 @Test 21 public void one2manydouble(){ 22 //可以通过部门获取该部分下所有员工(因为设置了从部门到员工的一对多关联) 23 String hql="from Dept"; 24 Session session = HibernateUtil.getSession(); 25 Query query = session.createQuery(hql); 26 List<Dept> list = query.list(); 27 for (Dept dept:list) { 28 System.out.println(dept.getDeptname()+"=================="); 29 //部门中有哪些员工 30 for (Emp emp:dept.getEmps()) { 31 System.out.println(emp.getEmpname()); 32 } 33 System.out.println("end===============end"); 34 } 35 36 37 //可以通过某个员工获取该员工所在的部门(因为设置了从员工到部门的多对一关联) 38 Emp emp=session.load(Emp.class,1); 39 System.out.println(emp.getDept().getDeptname()); 40 41 } 42 43 44 45 //01.关联查询,多对一单向关联 46 @Test 47 public void selectHibernateUtil(){ 48 //工具类 49 Session session=HibernateUtil.getSession(); 50 //提供一个员工的编号 51 Emp emp = session.get(Emp.class, 1); 52 System.out.println(emp.getEmpname()); 53 //隶属的部门 54 System.out.println(emp.getDept().getDeptname()); 55 } 56 57 //02.保存部门和员工 58 @Test 59 public void testSaveDeptAndEmp(){ 60 Session session=HibernateUtil.getSession(); 61 //事务的获取 62 Transaction tx=session.beginTransaction(); 63 64 Dept dept=new Dept(); 65 dept.setDeptname("哈哈啊"); 66 67 Emp emp=new Emp(); 68 emp.setEmpname("郝叔奥"); 69 //将部门的引入绑定到员工对象的一个属性上 70 dept.getEmps().add(emp); 71 emp.setDept(dept); 72 session.save(dept); 73 //session.save(emp); 74 tx.commit();//事务提交操作 75 } 76 @Test 77 //03.按照指定的部门对象,查询相关的Emp对象 78 public void t3(){ 79 Session session=HibernateUtil.getSession(); 80 //不好想 81 String hql="from Emp e where e.dept.deptno=1"; 82 Query query = session.createQuery(hql); 83 List<Emp> list = query.list(); 84 //输出部门信息 85 for (Emp item : list) { 86 System.out.println(item.getEmpname()); 87 } 88 session.close(); 89 } 90 //04.输出指定的emps集合中的所有emp对象及其所关联的部门对象的信息 91 @Test 92 public void t4(){ 93 Session session=HibernateUtil.getSession(); 94 String hql="from Emp"; 95 Query query = session.createQuery(hql); 96 List<Emp> list = query.list(); 97 //输出部门信息 98 for (Emp item : list) { 99 System.out.println("部门名称:"+item.getDept().getDeptname()); 100 System.out.println(item.getEmpname()); 101 } 102 session.close(); 103 } 104 @Test 105 //05.修改编号为1的员工所属的部门 106 public void t5(){ 107 Session session=HibernateUtil.getSession(); 108 Transaction tx=session.beginTransaction(); 109 Emp emp=session.load(Emp.class,1); 110 Dept dept=new Dept(); 111 dept.setDeptno(1); 112 emp.setDept(dept); 113 tx.commit(); 114 session.close(); 115 } 116 }
效果:
可以到这这里参考详细情况:https://www.cnblogs.com/liuling/archive/2013/01/14/231df213as32.html