Hibernate之关联关系映射(一对多和多对一映射,多对多映射)

~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习一下框架了,不然又被忽悠让去培训。)~~~

1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射:

  1.1:一对多和多对一映射,举例说明:

     学生和老师:

       一个老师可以教多个学生 【一对多映射】

      多个学生可以被一个老师教【多对一映射】

    部门与员工:

      一个部门有多个员工【一对多映射】

      多个员工属于一个部门【多对一映射】

  1.2:多对多,举例说明:

    项目和开发员工:【双向一对多即多对多映射】

      一个项目有多个开发人员【一对多】

         一个开发人员参与多个项目【一对多】


2:一对多和多对一映射,理清以下思路就可以进行简单的开发了:

  2.1:首先导入hibernate框架所需要的包哦~~~

  2.2:由于是在hibernate.cfg.xml配置里面自动生成数据库和表,所以不用手动创建了

  2.3:进入正题,开发创建实体类;下面是两个实体类的关键点;

    Dept.java:

      注意private Set emps;//部门对应多个员工,即一对多的关系

    Employee.java:

      private Dept dept;//员工和部门的关系

 1 package com.bie.po;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 /** 
 7 * @author BieHongLi 
 8 * @version 创建时间:2017年3月20日 上午9:45:21 
 9 * 部门的实体类
10 *     关键点,是通过部门实体类维护到员工的实体类
11 */
12 public class Dept {
13 
14     private int deptId;//部门编号
15     private String deptName;//部门名称
16     
17     private Set emps;//部门对应多个员工,即一对多的关系
18     //private Set emps = new HashSet<>();//方便赋值,这里可以直接创建实例化
19     
20     
21     public int getDeptId() {
22         return deptId;
23     }
24     public void setDeptId(int deptId) {
25         this.deptId = deptId;
26     }
27     public String getDeptName() {
28         return deptName;
29     }
30     public void setDeptName(String deptName) {
31         this.deptName = deptName;
32     }
33     public Set getEmps() {
34         return emps;
35     }
36     public void setEmps(Set emps) {
37         this.emps = emps;
38     }
39     
40     
41 }
View Code
 1 package com.bie.po;
 2 /** 
 3 * @author BieHongLi 
 4 * @version 创建时间:2017年3月20日 上午9:46:45 
 5 * 员工的实体类
 6 */
 7 public class Employee {
 8 
 9     private int empId;//员工的编号
10     private String empName;//员工的名称
11     private double salary;//员工的薪资
12     
13     private Dept dept;//员工和部门的关系
14     
15     public int getEmpId() {
16         return empId;
17     }
18     public void setEmpId(int empId) {
19         this.empId = empId;
20     }
21     public String getEmpName() {
22         return empName;
23     }
24     public void setEmpName(String empName) {
25         this.empName = empName;
26     }
27     public double getSalary() {
28         return salary;
29     }
30     public void setSalary(double salary) {
31         this.salary = salary;
32     }
33     public Dept getDept() {
34         return dept;
35     }
36     public void setDept(Dept dept) {
37         this.dept = dept;
38     }
39     
40     
41 }
View Code

  2.4:创建好实体类就可以进行创建hibernate的映射文件了,如Dept.hbm.xml和Employee.hbm.xml映射文件;

     部门表进行映射的时候:

      需要注意使用set集合进行映射的注意点:

Dept映射关键点:
1:指定映射的集合属性:"emps"
2:集合属性对应的集合表:"20171021_employee"
3:集合表的外键字段"20171021_employee.deptId"
4:集合元素的类型

    员工表进行映射的时候:

      需要注意

      将一个对象映射成为外键字段,只能使用many-to-one这个配置。

Employee映射关键点:
1:映射的部门属性:dept
2:映射的部门对象,对应的外键字段:dept_id
3:指定部门的类型

 

 1 
 2 mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5     
 6     
 7 package="com.bie.po">
 8     <class name="Dept" table="dept">
 9         
10         
11             class="native">
12         
13         
14         
15     
16         
19         
27                 
28         
29             
30             
31             
32             class="Employee"/>
33         
34     class>
35 
36     
37     
38     
 1 
 2 mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 
 6 package="com.bie.po">
 7     <class name="Employee" table="employee">
 8         
 9         
10             class="native">
11         
12         
13         
14         
15         
16         
17         
23          class="Dept">
24     class>
25 
26     
27     
28     

  2.5:配置好映射文件,就可以配置hibernate的配置文件了,hibernate.cfg.xml;

    注意:

      第二部分其他配置的时候注意显示sql语句和方言还有自动创建数据表这些细节问题

      第三部分加载映射文件的写法也需要注意

 1 configuration PUBLIC
 2     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 3     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 4     
 5 
 6     
 7         
 8         com.mysql.jdbc.Driver
 9         jdbc:mysql:///test
10         root
11         123456
12     
13         
14         org.hibernate.dialect.MySQLDialect
15         true
16         true
17         update
18         
19         
20         
21         
22         
23     
24 

  2.6:最后就可以使用junit进行测试了,如下所示:

    (1)首先清楚下面两种测试的区别是是否在实体类实例化set集合

        private Set emps;//部门对应多个员工,即一对多的关系
          private Set emps = new HashSet<>();//方便赋值,这里可以直接创建实例化

    (2)下面两种情况都可以设置好部门和员工的信息。就是在配置映射的时候一定搞清楚set集合映射的配置和many-to-one的配置

       I:从部门的一方设置员工的信息【不推荐】 

         dept.getEmps().add(emp1);
               dept.getEmps().add(emp2);
      
            II:从员工的一方设置好部门的信息【推荐,在一对多和多对一的关联关系中,保存数据最好是通过多对一来维护关系,这样可以减少update语句的生成,从而提高hibernate的利用效率】
              emp1.setDept(dept);
              emp2.setDept(dept);

    (3)最后是保存的顺序,保存的顺序最好是先保存一的一方再保存多的一方,这样可以提高效率,少执行sql语句

        第一种方法(推荐)

session.save(dept);//先保存一的一方
session.save(emp1);
session.save(emp2);//再保存多的一方,关系会自动维护(但是映射配置必须配置好的 )
                  

        第二种方法(不推荐)

session.save(emp1);//先保存多的一方,关系会自动维护(但是映射配置必须配置好的 )
session.save(emp2);
session.save(dept);//保存一的一方

  1 package com.bie.test;
  2 
  3 import java.util.HashSet;
  4 import java.util.Set;
  5 
  6 import org.hibernate.Session;
  7 import org.hibernate.SessionFactory;
  8 import org.hibernate.cfg.Configuration;
  9 import org.junit.Test;
 10 
 11 import com.bie.po.Dept;
 12 import com.bie.po.Employee;
 13 
 14 /** 
 15 * @author BieHongLi 
 16 * @version 创建时间:2017年3月20日 上午10:29:38 
 17 * 
 18 */
 19 public class OneManyTest {
 20 
 21     //初始化静态的session工厂
 22     private static SessionFactory sf = null;
 23     static{
 24         //这里使用简写的方法,首先加载默认的hibernate.cfg.xml,然后是创建session工厂
 25         sf = new Configuration().configure().buildSessionFactory();
 26     }
 27     
 28     @Test
 29     public void test(){
 30         //创建session,import org.hibernate.Session;
 31         Session session = sf.openSession();
 32         //session开始事务
 33         session.beginTransaction();
 34         
 35         //1:关键点,部门对象的初始化,创建一个部门
 36         Dept dept = new Dept();
 37         dept.setDeptName("开发部");
 38         
 39         //2:关键点,员工的初始化,创建两个人对象
 40         Employee emp1 = new Employee();
 41         emp1.setEmpName("张三");
 42         Employee emp2 = new Employee();
 43         emp2.setEmpName("李四");
 44         
 45         //3:然后将创建的人添加到set集合中
 46         Set set = new HashSet<>();
 47         set.add(emp1);
 48         set.add(emp2);
 49         
 50         //4:再将set集合中保存的人保存到部门里面
 51         dept.setEmps(set);
 52         
 53         //5:最后保存员工对象,部门
 54         session.save(emp1);
 55         session.save(emp2);
 56         session.save(dept);
 57         
 58         //提交事务,省去了事务new实例化了
 59         session.getTransaction().commit();
 60         //关闭session
 61         session.close();
 62     }
 63     
 64     @Test
 65     public void test2(){
 66         //创建session,import org.hibernate.Session;
 67         Session session = sf.openSession();
 68         //session开始事务
 69         session.beginTransaction();
 70         
 71         //1:关键点,部门对象的初始化,创建一个部门
 72         Dept dept = new Dept();
 73         dept.setDeptName("研发部2");
 74         
 75         //2:关键点,员工的初始化,创建两个人对象
 76         Employee emp1 = new Employee();
 77         emp1.setEmpName("小三子2");
 78         Employee emp2 = new Employee();
 79         emp2.setEmpName("小四子2");
 80         
 81         //3:再将set集合中保存的人保存到部门里面
 82         //dept.getEmps().add(emp1);
 83         //dept.getEmps().add(emp2);
 84         
 85         //或者是从员工的一方设置好部门的信息
 86         emp1.setDept(dept);
 87         emp2.setDept(dept);
 88         
 89         //4:最后保存员工对象,部门,保存的顺序也会影响sql语句的,所以最好先保存一的一方
 90         session.save(dept);//先保存一的一方
 91         session.save(emp1);
 92         session.save(emp2);//再保存多的一方,关系会自动维护(但是映射配置必须配置好的 )
 93         
 94         //提交事务,省去了事务new实例化了
 95         session.getTransaction().commit();
 96         //关闭session
 97         session.close();
 98     }
 99     
100 }

测试结果如下所示(由于set集合在实体类里面初始化和不初始化出现下面两种情况,所以需要注意两种测试测试的方法):


 3:多对多映射,这个需要理解清楚他们之间的关系。不然很容易搞混乱的。

  3.1:创建实体类:

    Project.java

      项目下面的多个员工
        private Set deve = new HashSet();

     Develope.java

     开发人员参入的多个项目
         private Set project = new HashSet(); 

 1 package com.bie.domain;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 /** 
 7 * @author BieHongLi 
 8 * @version 创建时间:2017年3月20日 下午5:32:42 
 9 * 项目的实体类
10 */
11 public class Project {
12 
13     private int proId;
14     private String proName;
15     
16     //项目下面的多个员工
17     private Set deve = new HashSet();
18 
19     public int getProId() {
20         return proId;
21     }
22     public void setProId(int proId) {
23         this.proId = proId;
24     }
25     public String getProName() {
26         return proName;
27     }
28     public void setProName(String proName) {
29         this.proName = proName;
30     }
31     public Set getDeve() {
32         return deve;
33     }
34     public void setDeve(Set deve) {
35         this.deve = deve;
36     }
37     
38 }
View Code
 1 package com.bie.domain;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 /** 
 7 * @author BieHongLi 
 8 * @version 创建时间:2017年3月20日 下午5:33:53 
 9 * 项目参入人员
10 */
11 public class Develope {
12 
13     private int deveId;
14     private String deveName;
15     
16     //开发人员参入的多个项目
17     private Set project = new HashSet();
18 
19     public int getDeveId() {
20         return deveId;
21     }
22     public void setDeveId(int deveId) {
23         this.deveId = deveId;
24     }
25     public String getDeveName() {
26         return deveName;
27     }
28     public void setDeveName(String deveName) {
29         this.deveName = deveName;
30     }
31     public Set getProject() {
32         return project;
33     }
34     public void setProject(Set project) {
35         this.project = project;
36     }
37     
38     
39 }
View Code

  3.2:如上面的,创建好实体类就可以配置就可以配置映射文件了:【注意,主键一定设置自增,开始我没写,报错了哦~~~】

    Project.hbm.xml:【关键点】

      
            
                
                
                
                
            

    Develope.hbm.xml:【关键点】

      
                
                
            

 1 
 2 mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 
 6 package="com.bie.domain">
 7     <class name="Project" table="project">
 8         
 9         
10             class="native">
11         
12         
13         
14         
15         
16         
25         
26           
27               
28               
29               
30               class="Develope">
31            
32          
33     class>
34     
35     
36     
37     
 1 
 2 mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 package="com.bie.domain">
 6     <class name="Develope" table="develope">
 7         
 8         
 9             class="native">
10         
11         
12         
13         
14         
15         
23         
24             
25             class="Project">
26          
27         
28     class>
29 
30 
31     
32     

  3.3:这里配置Hibernate.cfg.xml,和上面的配置类似。

   
        
        

 1 configuration PUBLIC
 2     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 3     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 4     
 5 
 6     
 7         
 8         com.mysql.jdbc.Driver
 9         jdbc:mysql:///test
10         root
11         123456
12     
13         
14         org.hibernate.dialect.MySQLDialect
15         true
16         
17         update 
18         
19         
20         
21         
22         
23         
24         
25         
26         
27         
28         
29     
30 
View Code

  3.4:最后测试就可以了,多对多的关系映射:

 1 package com.bie.test;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.cfg.Configuration;
 6 import org.junit.Test;
 7 
 8 import com.bie.domain.Develope;
 9 import com.bie.domain.Project;
10 
11 /** 
12 * @author BieHongLi 
13 * @version 创建时间:2017年3月20日 下午7:27:00 
14 * 多对多的测试
15 */
16 public class Many2ManyTest {
17 
18     public static SessionFactory sf =null;
19     static{
20         sf = new Configuration().configure().buildSessionFactory();
21     }
22     
23     @Test
24     public void test(){
25         Session session = sf.openSession();
26         session.beginTransaction();
27         
28         //创建项目和员工进行保存测试
29         Project pro1 = new Project();
30         pro1.setProName("企业费用管理系统");
31         Project pro2 = new Project();
32         pro2.setProName("企业办公系统");
33         
34         Develope dev1 = new Develope();
35         dev1.setDeveName("张三");
36         Develope dev2 = new Develope();
37         dev2.setDeveName("李四");
38         Develope dev3 = new Develope();
39         dev3.setDeveName("王五");
40         
41         //设置关系,
42         pro1.getDeve().add(dev1);
43         pro1.getDeve().add(dev2);
44         pro2.getDeve().add(dev1);
45         pro2.getDeve().add(dev3);
46         
47         //保存到session中,保存员工和项目到session中
48         session.save(dev1);
49         session.save(dev2);
50         session.save(dev3);
51 
52         session.save(pro1);
53         session.save(pro2);
54         
55         //提交
56         session.getTransaction().commit();
57         session.close();
58     }
59     
60 }

只有学习才能使我快乐~~~,加油~~~

你可能感兴趣的:(java,数据库,面试)