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

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

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

     学生和老师:

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

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

    部门与员工:

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

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

  1.2:多对多,举例说明:

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

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

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


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

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

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

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

    Dept.java:

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

    Employee.java:

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

 package com.bie.po;

 import java.util.HashSet;
import java.util.Set; /**
* @author BieHongLi
* @version 创建时间:2017年3月20日 上午9:45:21
* 部门的实体类
* 关键点,是通过部门实体类维护到员工的实体类
*/
public class Dept { private int deptId;//部门编号
private String deptName;//部门名称 private Set<Employee> emps;//部门对应多个员工,即一对多的关系
//private Set<Employee> emps = new HashSet<>();//方便赋值,这里可以直接创建实例化 public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Set<Employee> getEmps() {
return emps;
}
public void setEmps(Set<Employee> emps) {
this.emps = emps;
} }
 package com.bie.po;
/**
* @author BieHongLi
* @version 创建时间:2017年3月20日 上午9:46:45
* 员工的实体类
*/
public class Employee { private int empId;//员工的编号
private String empName;//员工的名称
private double salary;//员工的薪资 private Dept dept;//员工和部门的关系 public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
} }

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

     部门表进行映射的时候:

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

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

    员工表进行映射的时候:

      需要注意<many-to-one name="dept" column="deptId" class="Dept"></many-to-one>

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

Employee映射关键点:
:映射的部门属性:dept
:映射的部门对象,对应的外键字段:dept_id
:指定部门的类型
 <?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"> <!-- 如果hibernate-mapping的package属性直接初始化了,下面就可以直接引用了 -->
<hibernate-mapping package="com.bie.po">
<class name="Dept" table="dept">
<!-- 第一首先写主键映射 -->
<id name="deptId" column="deptId">
<generator class="native"></generator>
</id>
<!-- 第二写非主键映射 -->
<property name="deptName" column="deptName" length="20" type="string"></property> <!--
第三写其他映射,比如这里的set集合映射,
-->
<!--
一对多关联映射配置(通过部门管理到员工)
Dept映射关键点
(1)指定映射的集合属性:""emps;
(2)集合属性对应的集合表:"employee";
(3)集合表的外键字段:employee.empId
(4)集合元素的类型
-->
<!-- name指定了映射的集合的属性,即集合实例化的emps;table指定了集合属性对应的集合表 -->
<set name="emps" table="employee">
<!--column指定了集合表的外键 -->
<key column="deptId"></key>
<!-- class由于上面已经写了包名,这里直接使用即可 -->
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
 <?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,里面就可以直接引用了 -->
<hibernate-mapping package="com.bie.po">
<class name="Employee" table="employee">
<!-- 1:主键映射 -->
<id name="empId" column="empId">
<generator class="native"></generator>
</id> <!-- 2:非主键映射 -->
<property name="empName" column="empName" length="20" type="string"></property>
<property name="salary" column="salary" type="double"></property> <!--
多对一的映射配置;Employee映射的关键点
(1)映射的部门属性:dept
(2)映射的部门对新,对应的外键字段:deptId
(3)部门的类型:Dept
-->
<many-to-one name="dept" column="deptId" class="Dept"></many-to-one>
</class> </hibernate-mapping>

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

    注意:

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

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

 <!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- 第一部分:连接数据库的操作,加载驱动,连接数据库的url和账号密码 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property> <!-- 第二部分:其他相关配置 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- <property name="hibernate.hbm2ddl.auto">create</property> --> <!-- 第三部分:加载映射文件 -->
<mapping resource="com/bie/po/Dept.hbm.xml"/>
<mapping resource="com/bie/po/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

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

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

        private Set<Employee> emps;//部门对应多个员工,即一对多的关系
          private Set<Employee> 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);//再保存一的一方

 package com.bie.test;

 import java.util.HashSet;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test; import com.bie.po.Dept;
import com.bie.po.Employee; /**
* @author BieHongLi
* @version 创建时间:2017年3月20日 上午10:29:38
*
*/
public class OneManyTest { //初始化静态的session工厂
private static SessionFactory sf = null;
static{
//这里使用简写的方法,首先加载默认的hibernate.cfg.xml,然后是创建session工厂
sf = new Configuration().configure().buildSessionFactory();
} @Test
public void test(){
//创建session,import org.hibernate.Session;
Session session = sf.openSession();
//session开始事务
session.beginTransaction(); //1:关键点,部门对象的初始化,创建一个部门
Dept dept = new Dept();
dept.setDeptName("开发部"); //2:关键点,员工的初始化,创建两个人对象
Employee emp1 = new Employee();
emp1.setEmpName("张三");
Employee emp2 = new Employee();
emp2.setEmpName("李四"); //3:然后将创建的人添加到set集合中
Set<Employee> set = new HashSet<>();
set.add(emp1);
set.add(emp2); //4:再将set集合中保存的人保存到部门里面
dept.setEmps(set); //5:最后保存员工对象,部门
session.save(emp1);
session.save(emp2);
session.save(dept); //提交事务,省去了事务new实例化了
session.getTransaction().commit();
//关闭session
session.close();
} @Test
public void test2(){
//创建session,import org.hibernate.Session;
Session session = sf.openSession();
//session开始事务
session.beginTransaction(); //1:关键点,部门对象的初始化,创建一个部门
Dept dept = new Dept();
dept.setDeptName("研发部2"); //2:关键点,员工的初始化,创建两个人对象
Employee emp1 = new Employee();
emp1.setEmpName("小三子2");
Employee emp2 = new Employee();
emp2.setEmpName("小四子2"); //3:再将set集合中保存的人保存到部门里面
//dept.getEmps().add(emp1);
//dept.getEmps().add(emp2); //或者是从员工的一方设置好部门的信息
emp1.setDept(dept);
emp2.setDept(dept); //4:最后保存员工对象,部门,保存的顺序也会影响sql语句的,所以最好先保存一的一方
session.save(dept);//先保存一的一方
session.save(emp1);
session.save(emp2);//再保存多的一方,关系会自动维护(但是映射配置必须配置好的 ) //提交事务,省去了事务new实例化了
session.getTransaction().commit();
//关闭session
session.close();
} }

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


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

  3.1:创建实体类:

    Project.java

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

     Develope.java

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

 package com.bie.domain;

 import java.util.HashSet;
import java.util.Set; /**
* @author BieHongLi
* @version 创建时间:2017年3月20日 下午5:32:42
* 项目的实体类
*/
public class Project { private int proId;
private String proName; //项目下面的多个员工
private Set<Develope> deve = new HashSet<Develope>(); public int getProId() {
return proId;
}
public void setProId(int proId) {
this.proId = proId;
}
public String getProName() {
return proName;
}
public void setProName(String proName) {
this.proName = proName;
}
public Set<Develope> getDeve() {
return deve;
}
public void setDeve(Set<Develope> deve) {
this.deve = deve;
} }
 package com.bie.domain;

 import java.util.HashSet;
import java.util.Set; /**
* @author BieHongLi
* @version 创建时间:2017年3月20日 下午5:33:53
* 项目参入人员
*/
public class Develope { private int deveId;
private String deveName; //开发人员参入的多个项目
private Set<Project> project = new HashSet<Project>(); public int getDeveId() {
return deveId;
}
public void setDeveId(int deveId) {
this.deveId = deveId;
}
public String getDeveName() {
return deveName;
}
public void setDeveName(String deveName) {
this.deveName = deveName;
}
public Set<Project> getProject() {
return project;
}
public void setProject(Set<Project> project) {
this.project = project;
} }

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

    Project.hbm.xml:【关键点】

      <!-- 实体类set集合实例化的对象name和中间表table -->
             <set name="deve" table="relation">
                <!-- 设置项目的主键 -->
                <key column="proId"></key>
                <!-- 设置人员的主键作为中间表的外键和人员对应的实体类 -->
                <many-to-many column="deve_Id" class="Develope"></many-to-many>
            </set>

    Develope.hbm.xml:【关键点】

      <set name="project" table="relation">
                <key column="deveId"></key>
                <many-to-many column="proId" class="Project"></many-to-many>
             </set>

 <?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"> <hibernate-mapping package="com.bie.domain">
<class name="Project" table="project">
<!-- 主键映射 -->
<id name="proId" column="proId">
<generator class="native"></generator>
</id>
<!-- 非主键映射 -->
<property name="proName" column="proName" type="string" length="20"></property> <!-- 其他映射配置 -->
<!--
多对多映射:
1:映射的集合属性:deve
2:集合属性,对应的中间表:relation
3:外键字段:proId
4:外键字段,对应的中间表字段:deveId
5:集合属性元素的类型 -->
<!-- 实体类set集合实例化的对象name和中间表table -->
<set name="deve" table="relation">
<!-- 设置项目的主键 -->
<key column="proId"></key>
<!-- 设置人员的主键作为中间表的外键和人员对应的实体类 -->
<many-to-many column="deve_Id" class="Develope"></many-to-many>
</set> </class> </hibernate-mapping>
 <?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">
<hibernate-mapping package="com.bie.domain">
<class name="Develope" table="develope">
<!-- 主键映射 -->
<id name="deveId" column="deveId">
<generator class="native"></generator>
</id>
<!-- 非主键映射 -->
<property name="deveName" column="deveName"></property> <!-- 其他映射配置 -->
<!--
多对多映射:员工方
1:映射的集合属性:project
2:集合属性,对应的中间表:relation
3:外键字段:deveId
4:外键字段,对应的中间表字段:proId
5:集合属性元素的类型
-->
<set name="project" table="relation">
<key column="deveId"></key>
<many-to-many column="proId" class="Project"></many-to-many>
</set> </class> </hibernate-mapping>

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

   <!-- 第三部门:多对多映射的映射加载文件 -->
        <mapping resource="com/bie/domain/Project.hbm.xml"/>
        <mapping resource="com/bie/domain/Develope.hbm.xml"/>

 <!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- 第一部分:连接数据库的操作,加载驱动,连接数据库的url和账号密码 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property> <!-- 第二部分:其他相关配置 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<!-- <property name="hibernate.format_sql">true</property> -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- <property name="hibernate.hbm2ddl.auto">create</property> --> <!-- 第三部分:加载映射文件 -->
<mapping resource="com/bie/po/Dept.hbm.xml"/>
<mapping resource="com/bie/po/Employee.hbm.xml"/> <!-- 第三部门:多对多映射的映射加载文件 -->
<mapping resource="com/bie/domain/Project.hbm.xml"/>
<mapping resource="com/bie/domain/Develope.hbm.xml"/> </session-factory>
</hibernate-configuration>

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

 package com.bie.test;

 import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test; import com.bie.domain.Develope;
import com.bie.domain.Project; /**
* @author BieHongLi
* @version 创建时间:2017年3月20日 下午7:27:00
* 多对多的测试
*/
public class Many2ManyTest { public static SessionFactory sf =null;
static{
sf = new Configuration().configure().buildSessionFactory();
} @Test
public void test(){
Session session = sf.openSession();
session.beginTransaction(); //创建项目和员工进行保存测试
Project pro1 = new Project();
pro1.setProName("企业费用管理系统");
Project pro2 = new Project();
pro2.setProName("企业办公系统"); Develope dev1 = new Develope();
dev1.setDeveName("张三");
Develope dev2 = new Develope();
dev2.setDeveName("李四");
Develope dev3 = new Develope();
dev3.setDeveName("王五"); //设置关系,
pro1.getDeve().add(dev1);
pro1.getDeve().add(dev2);
pro2.getDeve().add(dev1);
pro2.getDeve().add(dev3); //保存到session中,保存员工和项目到session中
session.save(dev1);
session.save(dev2);
session.save(dev3); session.save(pro1);
session.save(pro2); //提交
session.getTransaction().commit();
session.close();
} }

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

Hibernate之关联关系映射(一对多和多对一映射,多对多映射)的更多相关文章

  1. Hibernate笔记——关联关系配置(一对多、一对一和多对多)

    原文:http://www.cnblogs.com/otomedaybreak/archive/2012/01/20/2327695.html ============================ ...

  2. 攻城狮在路上(壹) Hibernate(五)--- 映射一对多关联关系

    关联是有方向的,包含单向关联和双向关联.分别讨论.本文以客户Customer和订单Order来进行讨论:一个Customer有多个Order,每个Order对应一个Customer. Customer ...

  3. Hibernate关联关系配置(一对多、一对一和多对多)

    第一种关联关系:一对多(多对一) "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系. 一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多. 多对一:从订单的 ...

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

    ~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习以下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...

  5. Hibernate关联关系配置(一对多,一对一,多对多)

    一对多 创建两个类  Manager(一这一端) Worker(多这一端)  即一个经理下有多个员工 package com.hibernate.n21; import java.util.HashS ...

  6. (转)Hibernate关联映射——一对多(多对一)

    http://blog.csdn.net/yerenyuan_pku/article/details/70152173 Hibernate关联映射——一对多(多对一) 我们以客户(Customer)与 ...

  7. hibernate映射(一对一、一对多、多对一、多对多)配置 【转】

    多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一 一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多 也就是说一对多和多对一的映射策略是一样的,只是站 ...

  8. Hibernate 实体关联关系映射【转】

    Hibernate关联关系映射目录│ ├─单向关联│  ├─  一对一外键单向关联│  ├─  一对一主键单向关联│  ├─  一对一连接表单向关联│  ├─  一对多外键单向关联│  ├─  一对多 ...

  9. Hibernate 实体关联关系映射----总结

    在我看来,Hibernate提供这些映射关系,常用就是一对一和多对一,并且在能不用连接表的时候尽量不要用连接表.多对多会用到,如果用到了,应该首先考虑底层数据库设计是否合理.   在实际开发中,在Hi ...

随机推荐

  1. Access restriction: The constructor SunJCE() is not accessible 错误

    Access restriction: The type 'SunJCE' is not API (restriction on required library 'C:\Program Files\ ...

  2. 矩阵乘法np.dot()及np.multipy()区别

    1. 线性代数中矩阵乘法: np.dot() import numpy as np ​ # 2 x 3 matrix1 = np.array([[1, 2, 3], [4, 5, 6]]) ​ # 3 ...

  3. 13. Spring Boot 拦截器

    1.thymeleaf  页面修改后可能不会实时反馈到Web,做2步骤: 1)禁用掉tymleaf 缓存: spring.thymeleaf.cache=false 2)IDE编辑器:Ctrl + F ...

  4. NOIP2018ty记

    前置传送门:noip2018前流水账 Day-inf~Day-3 写流水账里了 懒得再写了 Day-2~Day-1 做了些noip的原题 真是奇怪,我天天爱跑步和逛公园都是1A的,结果反而有些普及组的 ...

  5. 2016年1月7日 隐藏NavigationBar时的一个坑

    http://www.jianshu.com/p/efb960fed457 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear: ...

  6. windows cmd相关操作

    一:文件夹1. 新建文件夹方式一:md[盘符:\][路径\]新目录例如:md c:\test\newtest 方式二:先使用cmd进入需要新建文件的根目录下,使用md或者mkdir 直接创建文件夹ne ...

  7. Kali2.0更新

    下载链接:猛戳这里 更新以后速度与界面友好性提高了! 界面仿造了ubuntu和fedora,应用也有很多小图标!这个对个人来说比较赞 安装以后的几件事 1.安装vmtools,方法跟1.0一样! ta ...

  8. Arduino语法详解_含示例详解

    Arduino 的程序可以划分为三个主要部分:结构.变量(变量与常量).函数. 结构部分 一.结构 1.1 setup() 1.2 loop() 二.结构控制 2.1 if 2.2 if...else ...

  9. Node.jsでMySQLを使うメモ

    インストール npm install mysql コネクション var mysql = require('mysql'); var connection = mysql.createConnectio ...

  10. java.sql.SQLException: ORA-28040: 没有匹配的验证协议(12c或者12c rac)

    1.plsql可以连接,java程序不能连接,报如下错误: 一直以来用的都是服务器上的Oracle数据库,今天改成连接本地Oracle 12c数据库是出问题了.hibernate连接Oracle12c ...