如果仅有从Emp到Dept对象的关联,(多个员工对应一个部门)多对一的关系

(多个员工对应一个部门)多对一的关系, 一、用员工和部门来剖析关联映射的原理,这就意味着每个Emp对象只会引用一个Dept对象,如果仅有从Emp到Dept对象的关联,在对象模型中就是一个或多个引用

图片 21
<?"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="cn.happy.entity">  <class name="Dept" table="DEPT">  <!-- <cache usage="read-write"/> -->   <id name="deptNo">    <generator class="sequence">     <param name="sequence">SEQ_NUM</param>    </generator>   </id>    <property name="deptName"/>  </class></hibernate-mapping>

如果仅有从Emp到Dept对象的关联,或者仅有从Dept到Emp的关联,就称为单向关联。如果同时包含两种关联,就称为双向关联。

二:配置双向的一对多关联

在上一个例子中,已经建立Emp类到Dept类的多对一关联,下面再增加Dept到Emp类的一对多关联,

在Dept类中增加一个集合类型的emps属性:

    private Set<Emp> emps=new HashSet<Emp>();//员工集合

    public Set<Emp> getEmps() {
        return emps;
    }

    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }

在Dept.hbm.xml中也会改变为:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Dept" table="DEPT">
<id name="deptid" column="DEPTID">
   <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="deptname" type="string" column="deptname"/>
<!-- 映射集合类型的emps属性 -->
<!-- name属性:设定持久化类的属性名。此处为Dept类的emps -->
<set name="emps" cascade="save-update" inverse="true">
<!-- column属性设定与所关联的持久化类对应的表的外键,此处为EMP表的deptid字段 -->
<key column="deptid"></key>
<!-- class属性设定与所关联的持久化类,此处为Emp类 -->
<one-to-many class="Emp"></one-to-many>
</set>
</class>
</hibernate-mapping>

补充:cascade属性和inverse属性(会新写一篇博客)

 01.”cascade”属性

 
 ”cascade”-直译过来就是”级联、串联”的意思,书面化的解释为”该属性会使我们在操作主对象时,同时Hibernate帮助我们完成从属对象
相应的操作(比如,有Customer和Order这两张表,关系为一对多,只使用JDBC删除Customer表中的一行记录时,我们还需要手动的将
Order表中与之关联的记录全都删除,使用Hibernate的’cascade’属性后,当我们删除一条Customer记录时,Hibernate
会帮助我们完成相应Order表记录的删除工作,方便了我们的工作)”。

 02.”inverse”属性

       “inverse”
-直译过来就是”反转,使颠倒”的意思,书面化的解释为”是否将关系维护的权力交给对方”(这个解释真够蛋疼的-_-!!,就是理解不了)。 Hibernate中的”inverse”属性只有两个值”true”和”false”。”true”表示将关系维护的权力交给对方,”false”表示不交出维护权力(默认值)。

推荐博客:

测试:

    @Test  
    public void TestThree(){
        //获得session对象
        Session session = HibernateUtil.currentSession();
        //开启事务
        Transaction tx = session.beginTransaction();
        //建立一个Dept对象和Emp对象

        Dept dept=new Dept();
        dept.setDeptname("就业部");

        Emp emp=new Emp();
        emp.setEmpname("坤坤");
        //建立Dept和Emp对象的一对多双向关联关系
        emp.setDept(dept);    
        dept.getEmps().add(emp);
        //保存Dept对象
        session.save(dept);

        //提交事务
        tx.commit();
        //关闭session连接
        HibernateUtil.closeSession();

    }

 

如上图所示:满足多对一和一对多的关联就是双向关联。

二.配置单向多对一关联

 在Emp类中定义一个Dept属性,而在Dept类中无须定义用于存放Emp对象的集合属性

 01.Dept.java

图片 1

package cn.zhang.entity;

//部门实体类
public class Dept {

    private Integer deptid;//编号

    private String deptname;//名称


    public Integer getDeptid() {
        return deptid;
    }

    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }

    public String getDeptname() {
        return deptname;
    }

    public void setDeptname(String deptname) {
        this.deptname = deptname;
    }

}

图片 2

02.Emp.java

图片 3

package cn.zhang.entity;
//员工实体类
public class Emp {

    private Integer empno;//编号

    private String empname;//姓名

    private Dept dept;//所属部门


    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

}

图片 4

03.Dept.hbm.xml

图片 5

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Dept" table="DEPT">
<!--主键生成策略-->
<id name="deptid" column="DEPTID">
   <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="deptname" type="string" column="deptname"/>
</class>
</hibernate-mapping>

图片 6

04.Emp.hbm.xml

图片 7

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Emp" table="EMP">
<!-- 主键生成策略 -->
<id name="empno" column="empno">
    <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="empname" type="string" column="empname"/>
<!-- 多对一(员工对部门) -->
 <many-to-one name="dept" column="deptid" class="Dept"></many-to-one> 
</class>
</hibernate-mapping>

图片 8

05.hibernate.cfg.xml  配置文件

图片 9

<?xml version='1.0' encoding='utf-8'?>
<!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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <property name="connection.username">zhangzong</property>
        <property name="connection.password">123</property>

        <!-- SQL dialect (SQL 方言)-->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

        <!-- Drop and re-create the database schema on startup -->
         <property name="hbm2ddl.auto">create</property> 

        <!-- Echo all executed SQL to stdout  在控制台打印后台的SQL语句-->
        <property name="show_sql">true</property>

        <!-- 格式化显示SQL -->
        <property name="format_sql">true</property>    

        <!-- JDBC connection pool (use the built-in) -->
        <!-- <property name="connection.pool_size">1</property> -->

        <!-- Enable Hibernate's automatic session context management 指定当前session范围和上下文-->
        <!--  <property name="current_session_context_class">thread</property> -->

        <!-- Disable the second-level cache -->
        <!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>-->

        <mapping resource="cn/zhang/entity/Dept.hbm.xml" />
        <mapping resource="cn/zhang/entity/Emp.hbm.xml" />


    </session-factory>

</hibernate-configuration>

图片 10

06.用于获得session对象和关闭session对象的工具类HibernateUtil 

图片 11

package cn.zhang.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    //初始化一个ThreadLocal对象,有get和set方法
    private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();

    private static Configuration configuration;

    private final static SessionFactory sessionFactory;
    static{

        configuration=new Configuration().configure();
        sessionFactory=configuration.buildSessionFactory();
    }
    //获得session对象
    public static Session currentSession() {
        //sessionTL的get方法根据当前线程返回其对应的线程内部变量,即Session对象,多线程情况下共享数据库连接是不安全的。
        //ThreadLocal保证了每个线程都有自己的session对象
        Session session=(Session)sessionTL.get();
        if (session==null) {
            session=sessionFactory.openSession();
            sessionTL.set(session);
        }

        return session;
    }
    //关闭session对象
    public static void closeSession() {
        Session session=(Session)sessionTL.get();
        sessionTL.set(null);
        session.close();
    }

}

图片 12

07.测试类

图片 13

@Test //多对一的单向关联关系
    public void TestOne(){

        Session session = HibernateUtil.currentSession();

        Transaction tx = session.beginTransaction();
        Dept dept=new Dept();
        dept.setDeptname("开发部");

        Emp emp=new Emp();
        emp.setDept(dept);
        emp.setEmpname("张总");

        session.save(dept);
        session.save(emp);

        tx.commit();

        HibernateUtil.closeSession();        
    }

图片 14

四:建立多对多双向关联 拆成两个一对多  –利用第三张表建立两张表之间的联系

主要思想:新建立一个关系实体类和两张表关联的映射文件,主要在此映射文件中配置关联关系,其他两个映射文件只要配置基础映射

ProEmp.java

package cn.zhang.entity;
//关联实体类
public class ProEmp {
    private Integer id;
    private Project pro; //项目集合
    private Emp emp; //部门集合
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Project getPro() {
        return pro;
    }
    public void setPro(Project pro) {
        this.pro = pro;
    }
    public Emp getEmp() {
        return emp;
    }
    public void setEmp(Emp emp) {
        this.emp = emp;
    }

}

Emp.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

//员工实体类
public class Emp {

    private Integer empno;

    private String empname;

    private Set<ProEmp> projects = new HashSet<ProEmp>();//与ProEmp关联

    public Set<ProEmp> getProjects() {
        return projects;
    }

    public void setProjects(Set<ProEmp> projects) {
        this.projects = projects;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }



}

Project.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

//员工实体类
public class Emp {

    private Integer empno;

    private String empname;

    private Set<ProEmp> projects = new HashSet<ProEmp>();//与ProEmp关联

    public Set<ProEmp> getProjects() {
        return projects;
    }

    public void setProjects(Set<ProEmp> projects) {
        this.projects = projects;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

}

Emp.hbm.xml  

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Emp" table="EMP">
        <id name="empno" column="empno">
            <generator class="sequence">
                <param name="sequence">SQ_Num</param>
            </generator>
        </id>
        <property name="empname" type="string" column="empname" />
    </class>
</hibernate-mapping>

Project.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Project" table="PROJECT">
        <id name="proid" type="java.lang.Integer">
            <generator class="sequence">
          <param name="sequence">SQ_Num</param>
           </generator>
        </id>
        <property name="proname" type="java.lang.String" column="PRONAME"/>    
    </class>
</hibernate-mapping>

最后别忘了在大配置中配置引用映射文件哦!

测试:

 

@Test
    public void TestOne(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //创建EMP对象
        Emp emp=new Emp();
        emp.setEmpname("李小龙");

        //创建Pro对象
        Project pro=new Project();
        pro.setProname("海淀花园");

        ProEmp pEmp=new ProEmp();    

           //指定工程需要的员工
           pEmp.setEmp(emp);
           //指定员工所属的工程
        pEmp.setPro(pro);

        session.save(pro);
        session.save(emp);
        session.save(pEmp);


        // 事务提交
        tx.commit();

        HibernateUtil.closeSession();
    }

 

 

 

 

<?"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="cn.happy.entity">  <class name="Dept" table="DEPT">  <!-- <cache usage="read-write"/> -->   <id name="deptNo">    <generator class="sequence">     <param name="sequence">SEQ_NUM</param>    </generator>   </id>    <property name="deptName"/>   <set name="emps">    <key column="deptNo"></key>    <one-to-many class="Emp" />   </set>  </class></hibernate-mapping>

三.配置双向的一对多关联

在上一个例子中,已经建立Emp类到Dept类的多对一关联,下面再增加Dept到Emp类的一对多关联,

在Dept类中增加一个集合类型的emps属性:

图片 15

    private Set<Emp> emps=new HashSet<Emp>();//员工集合

    public Set<Emp> getEmps() {
        return emps;
    }

    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }

图片 16

在Dept.hbm.xml中也会改变为:

图片 17

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Dept" table="DEPT">
<id name="deptid" column="DEPTID">
   <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="deptname" type="string" column="deptname"/>
<!-- 映射集合类型的emps属性 -->
<!-- name属性:设定持久化类的属性名。此处为Dept类的emps -->
<set name="emps" cascade="save-update" inverse="true">
<!-- column属性设定与所关联的持久化类对应的表的外键,此处为EMP表的deptid字段 -->
<key column="deptid"></key>
<!-- class属性设定与所关联的持久化类,此处为Emp类 -->
<one-to-many class="Emp"></one-to-many>
</set>
</class>
</hibernate-mapping>

图片 18

补充:cascade属性和inverse属性(会新写一篇博客)

 01.”cascade”属性

 
 ”cascade”-直译过来就是”级联、串联”的意思,书面化的解释为”该属性会使我们在操作主对象时,同时Hibernate帮助我们完成从属对象
相应的操作(比如,有Customer和Order这两张表,关系为一对多,只使用JDBC删除Customer表中的一行记录时,我们还需要手动的将
Order表中与之关联的记录全都删除,使用Hibernate的’cascade’属性后,当我们删除一条Customer记录时,Hibernate
会帮助我们完成相应Order表记录的删除工作,方便了我们的工作)”。

 02.”inverse”属性

       “inverse”
-直译过来就是”反转,使颠倒”的意思,书面化的解释为”是否将关系维护的权力交给对方”(这个解释真够蛋疼的-_-!!,就是理解不了)。 Hibernate中的”inverse”属性只有两个值”true”和”false”。”true”表示将关系维护的权力交给对方,”false”表示不交出维护权力(默认值)。

推荐博客:

测试:

图片 19

    @Test  
    public void TestThree(){
        //获得session对象
        Session session = HibernateUtil.currentSession();
        //开启事务
        Transaction tx = session.beginTransaction();
        //建立一个Dept对象和Emp对象

        Dept dept=new Dept();
        dept.setDeptname("就业部");

        Emp emp=new Emp();
        emp.setEmpname("坤坤");
        //建立Dept和Emp对象的一对多双向关联关系
        emp.setDept(dept);    
        dept.getEmps().add(emp);
        //保存Dept对象
        session.save(dept);

        //提交事务
        tx.commit();
        //关闭session连接
        HibernateUtil.closeSession();

    }

图片 20

 

三:配置双向多对多关联    –利用第三张表建立两张表之间的联系

对于双向多对多关联,需要把一端的inverse属性设为true,关联的两端都可以使用<set>元素。

Project类–定义集合类型的emps属性

Emp类–定义集合类型的projects属性

Project.java:

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

public class Project {
    private Integer proid;
    private String proname;
    private Set<Emp> emps = new HashSet<Emp>();
    public Integer getProid() {
        return proid;
    }
    public void setProid(Integer proid) {
        this.proid = proid;
    }
    public String getProname() {
        return proname;
    }
    public void setProname(String proname) {
        this.proname = proname;
    }
    public Set<Emp> getEmps() {
        return emps;
    }
    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }



}

 

Emp.java:

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

//员工实体类
public class Emp {

    private Integer empno;

    private String empname;

    private Set<Project> projects = new HashSet<Project>();

    public Set<Project> getProjects() {
        return projects;
    }

    public void setProjects(Set<Project> projects) {
        this.projects = projects;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

}

Project.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Project" table="PROJECT">
        <id name="proid" type="java.lang.Integer">
            <generator class="sequence">
          <param name="sequence">SQ_Num</param>
           </generator>
        </id>
        <property name="proname" type="java.lang.String" column="PRONAME"/>
        <!-- 多对多关联 -->
        <set name="emps" table="PROEMP" cascade="save-update"  >
            <key column="proid" />
            <many-to-many class="Emp" column="empno" />             
        </set>      
    </class>
</hibernate-mapping>

Emp.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Emp" table="EMP">
        <id name="empno" column="empno">
            <generator class="sequence">
                <param name="sequence">SQ_Num</param>
            </generator>
        </id>
        <property name="empname" type="string" column="empname" />

        <!--多对多关联 -->
        <set name="projects" table="PROEMP" cascade="save-update" inverse="true">
            <key column="empno" />
            <many-to-many class="Project" column="proid" />
        </set>
    </class>
</hibernate-mapping>

测试:

@Test
    public void TestOne(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //创建EMP对象
        Emp emp=new Emp();
        emp.setEmpname("李小龙");
        Emp emp2=new Emp();
        emp2.setEmpname("小龙");
        Emp emp3=new Emp();
        emp3.setEmpname("李龙");
        //创建Pro对象
        Project pro=new Project();
        pro.setProname("海淀花园");
        Project pro2=new Project();
        pro2.setProname("海淀花园fd");
        //指定工程需要的员工
        pro.getEmps().add(emp);
        pro.getEmps().add(emp2);
        pro.getEmps().add(emp3);

        pro2.getEmps().add(emp3);
        pro2.getEmps().add(emp2);
        //指定员工所属的工程
        //emp.getProjects().add(pro);

        session.save(pro);
        session.save(pro2);

        // 事务提交
        tx.commit();

        HibernateUtil.closeSession();
    }

注意:双向多对多,还可以拆成两个多对一

@Test    public void AddObjectToDept(){      Emp emps=new Emp();      emps.setEmpName("西丽");    Session session=HibernateUtil.currentSession();      Transaction tx = session.beginTransaction();    session.save(emps);    System.out.println("ok");    tx.commit();    HibernateUtil.closeSession();    }

一.关联关系  

三:配置单向多对多关联  –利用第三张表建立两张表之间的联系

建立从Project(项目)类到Emp(员工)类的单向多对多关联。

需在Project定义集合类型emps属性,Emp类中不需要定义集合类型的projects属性。

Project.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;
public class Project {
    private Integer proid;
    private String proname;
    private Set<Emp> emps = new HashSet<Emp>();
    public Integer getProid() {
        return proid;
    }
    public void setProid(Integer proid) {
        this.proid = proid;
    }
    public String getProname() {
        return proname;
    }
    public void setProname(String proname) {
        this.proname = proname;
    }
    public Set<Emp> getEmps() {
        return emps;
    }
    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }        

}

Project.hbm.xml     –利用第三张表建立两张表之间的联系

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Project" table="PROJECT">
        <id name="proid" type="java.lang.Integer">
            <generator class="sequence">
          <param name="sequence">SQ_Num</param>
           </generator>
        </id>
        <property name="proname" type="java.lang.String" column="PRONAME"/>
        <!-- 多对多关联 -->
        <set name="emps" table="PROEMP" cascade="save-update"  >
            <key column="proid" />
            <many-to-many class="Emp" column="empno" />             
        </set>      
    </class>
</hibernate-mapping>

测试:

    @Test
    public void TestOne(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //创建EMP对象
        Emp emp=new Emp();
        emp.setEmpname("李小龙");

        //创建Pro对象
        Project pro=new Project();
        pro.setProname("海淀花园");

        //指定工程需要的员工
        pro.getEmps().add(emp);

        session.save(pro);

        // 事务提交
        tx.commit();

        HibernateUtil.closeSession();
    }
cascade属性值               描述                    
none       当Session操纵当前对象,忽略其它的关联对象   cascade的默认值none
save-update       保存或者更新数据
delete     当通过Session的delete()方法删除当前对象时会级联删除所有的关联的对象
all     包含save—update和delete

在软件开发中,类与类中之间最普遍的关系就是关联关系,而且关联是有方向的。

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用。

 

 一个部门下可以有多个员工,而一个员工只能属于一个部门。所以从Emp到Dept的关联是一对多的关联关系,这就意味着每个Emp对象只会引用一个Dept对象。

一:配置单向多对一关联

 在Emp类中定义一个Dept属性,而在Dept类中无须定义用于存放Emp对象的集合属性

 01.Dept.java

package cn.zhang.entity;

//部门实体类
public class Dept {

    private Integer deptid;//编号

    private String deptname;//名称


    public Integer getDeptid() {
        return deptid;
    }

    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }

    public String getDeptname() {
        return deptname;
    }

    public void setDeptname(String deptname) {
        this.deptname = deptname;
    }

}

02.Emp.java

package cn.zhang.entity;
//员工实体类
public class Emp {

    private Integer empno;//编号

    private String empname;//姓名

    private Dept dept;//所属部门


    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

}

03.Dept.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Dept" table="DEPT">
<!--主键生成策略-->
<id name="deptid" column="DEPTID">
   <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="deptname" type="string" column="deptname"/>
</class>
</hibernate-mapping>

04.Emp.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Emp" table="EMP">
<!-- 主键生成策略 -->
<id name="empno" column="empno">
    <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="empname" type="string" column="empname"/>
<!-- 多对一(员工对部门) -->
 <many-to-one name="dept" column="deptid" class="Dept"></many-to-one> 
</class>
</hibernate-mapping>

05.hibernate.cfg.xml  配置文件

<?xml version='1.0' encoding='utf-8'?>
<!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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <property name="connection.username">zhangzong</property>
        <property name="connection.password">123</property>

        <!-- SQL dialect (SQL 方言)-->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

        <!-- Drop and re-create the database schema on startup -->
         <property name="hbm2ddl.auto">create</property> 

        <!-- Echo all executed SQL to stdout  在控制台打印后台的SQL语句-->
        <property name="show_sql">true</property>

        <!-- 格式化显示SQL -->
        <property name="format_sql">true</property>    

        <!-- JDBC connection pool (use the built-in) -->
        <!-- <property name="connection.pool_size">1</property> -->

        <!-- Enable Hibernate's automatic session context management 指定当前session范围和上下文-->
        <!--  <property name="current_session_context_class">thread</property> -->

        <!-- Disable the second-level cache -->
        <!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>-->

        <mapping resource="cn/zhang/entity/Dept.hbm.xml" />
        <mapping resource="cn/zhang/entity/Emp.hbm.xml" />


    </session-factory>

</hibernate-configuration>

06.用于获得session对象和关闭session对象的工具类HibernateUtil 

package cn.zhang.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    //初始化一个ThreadLocal对象,有get和set方法
    private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();

    private static Configuration configuration;

    private final static SessionFactory sessionFactory;
    static{

        configuration=new Configuration().configure();
        sessionFactory=configuration.buildSessionFactory();
    }
    //获得session对象
    public static Session currentSession() {
        //sessionTL的get方法根据当前线程返回其对应的线程内部变量,即Session对象,多线程情况下共享数据库连接是不安全的。
        //ThreadLocal保证了每个线程都有自己的session对象
        Session session=(Session)sessionTL.get();
        if (session==null) {
            session=sessionFactory.openSession();
            sessionTL.set(session);
        }

        return session;
    }
    //关闭session对象
    public static void closeSession() {
        Session session=(Session)sessionTL.get();
        sessionTL.set(null);
        session.close();
    }

}

07.测试类

@Test //多对一的单向关联关系
    public void TestOne(){

        Session session = HibernateUtil.currentSession();

        Transaction tx = session.beginTransaction();
        Dept dept=new Dept();
        dept.setDeptname("开发部");

        Emp emp=new Emp();
        emp.setDept(dept);
        emp.setEmpname("张总");

        session.save(dept);
        session.save(emp);

        tx.commit();

        HibernateUtil.closeSession();        
    }

   方法:Dept类中应该定义一个集合类型属性,来引用所有关联的Emp对象。

从Dept到Emp是一对多的关联关系,这意味着Dept对象会引用一组Emp对象,因此在Dept类中应该定义一个集合类型的属性,来引用所关联的Emp对象。

  第三步创建小配置Emp

   以部门(Dept)和员工(Emp)为例:

  图片 21

  与上述步骤唯一不同的就是Dept.hbm.

  解析:我们可以在<set>、<many-to-one>元素里面写cascade=“delete”属性就能完成并级联删除

            <key column="deptNo"></key>             <one-to-many />         </set>

  第二步建立大配置

第四步创建小配置Dept