文档章节

Hibernate之关联映射

刺猬一号
 刺猬一号
发布于 2017/05/08 02:41
字数 1669
阅读 6
收藏 0
一.关联关系  

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

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

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

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

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

二.配置单向多对一关联
 在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();        
    }
复制代码
复制代码
三.配置双向的一对多关联
在上一个例子中,已经建立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"表示不交出维护权力(默认值)。

推荐博客:http://www.cnblogs.com/o-andy-o/archive/2012/03/26/2418235.html

测试:

复制代码
复制代码
    @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();

    }
复制代码
复制代码
 

 

本文转载自:

刺猬一号
粉丝 12
博文 373
码字总数 616361
作品 0
深圳
私信 提问
Hibernate映射——一对一双向关联映射(六)

我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。如图所示: 关键原因在于对象模型具有方向性: 单向:一...

architect刘源源
2018/01/11
3
0
Hibernate映射——一对一单向关联映射(五)

映射原理 两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应。例如:一个人(Person)只有一张身份证(IdCard)。我们看一下这个例子的对象模型,如下图所示: 对象...

architect刘源源
2018/01/11
2
0
Hibernate映射——一对多关联映射(七)

一对多关联映射 映射原理 一对多关联映射和多对一的关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。关联关系都是由多端维护,只是在写映射时发生了变化。 多对一和...

architect刘源源
2018/01/11
3
0
Hibernate映射——多对一单向关联映射(四)

这篇博客,我们开始介绍基于基本映射的关联关系映射。 概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一...

architect刘源源
2018/01/11
3
0
Hibernate系列——总结篇(九)

概念 Hibernate是一个对象关系映射框架,当然从分层的角度看,我们也说它是数据持久层的框架。 我们从上一句话可以看出Hibernate的核心:面向对象、关系映射以及数据持久化。前面两个概念很容...

architect刘源源
2018/01/11
5
0

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
8
0
多线程同时加载缓存实现

import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorServi......

暗中观察
昨天
2
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
2
0
组装一台工作游戏两用机

一、配置清单如下: 分类 项目 价格(元) 主板 华硕(ASUS)TUF Z370-PLUS GAMING II 电竞特工 Z370二代 支持9代CPU 1049 CPU 英特尔(Intel) i7 8700K 酷睿六核 盒装CPU处理器 2640 风扇 九...

mbzhong
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部