Hibernate中一对多关系的映射配置

上篇内容简单回顾

1、Hibernate的持久化类的编写规则

(1)无参数构造
(2)属性私有
(3)属性尽量使用包装类
(4)提供一个唯一OID与主键对应
(5)不要使用final修饰


2、Hibernate的主键生成策略

主键分类:自然主键,代理主键。

主键生成策略类型:
(1)increment
(2)identity
(3)sequence
(4)uuid
(5)native
(6)assigned
(7)foreign


3、Hibernate的持久化类的三种状态

(1)瞬时态:没有唯一标识OID,没有被session管理。
(2)持久态:有唯一标识OID,已经被session管理。
(3)脱管态:有唯一标识OID,没有被session管理。

三种状态的互相转换:(了解)


4、Hibernate的一级缓存

(1)一级缓存:Hibernate优化手段,称为是session级别缓存。
(2)一级缓存特殊区域:快照区。


5、Hibernate的事务管理

(1)事务的回顾
事务的概念
事务的特性
引发安全性问题
安全性问题解决

(2)Hibernate解决读问题
需要配置隔离级别。

(3)Hibernate解决Service事务
采用的是线程绑定的方式。


6、Hibernate的其他的API

(1)Query:HQL,面向对象方式的查询。
(2)Criteria:QBC,完全面向对象化。
(3)SQLQuery:SQL,语句查询。


Hibernate中一对多关系的映射配置

1、数据库表与表之间的关系

(1)一对多关系
什么样关系属于一对多?
一个部门对应多个员工,一个员工只能属于某一个部门。
一个客户对应多个联系人,一个联系人只能属于某一个客户。

建表原则:一对多,2张表,多的表加外键。

(2)多对多关系
什么样关系属于多对多?
一个学生可以选择多门课程,一门课程也可以被多个学生选择。
一个用户可以选择多个角色,一个角色也可以被多个用户选择。

建表原则:多对多,3张表,关系表加外键。

(3)一对一关系(了解)
什么样关系属于一对一?
一个公司只能有一个注册地址,一个注册地址只能被一个公司注册。

一对一的建表原则:一般设置为一张表,作为属性处理。
如果应特殊要求,设置为两张表,有2种方式:唯一外键,主键对应。


2、Hibernate一对多的关系配置

(1)前期准备
引入jar包,准备数据库中的一对多的2张表。
假设有这2张表:部门表dept,员工表emp。

(2)编写持久化实体类

Dept类:

package com.pipi.hibernate03;
import java.util.HashSet;
import java.util.Set;

// 持久化实体类:部门,Dept
public class Dept {

    private Integer deptno;
    private String dname;
    private String loc;
    // 一个部门有多个员工,建议使用set集合
    private Set<Emp> emps = new HashSet<Emp>();

    // setter and getter
    // .....

    public Dept() {
    }

    public Dept(Integer deptno, String dname, String loc) {
        this.deptno = deptno;
        this.dname = dname;
        this.loc = loc;
    }

    @Override
    public String toString() {
        // ......
    }
}

Emp类:

package com.pipi.hibernate03;

// 持久化实体类:员工类,Emp
public class Emp {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private String hiredate;
    private Double sal;
    private Double comm;
    // 一个员工只属于一个部门
    private Dept dept;

	// setter and getter
	// ......

    public Emp() {
    }

    @Override
    public String toString() {
        //....
    }
}

(3)编写映射配置文件

Dept类映射dept表:Dept.hbm.xml映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- 建立类与表的映射 -->
    <class name="com.pipi.hibernate03.Dept" table="dept">

        <!-- 建立类中的OID与表中的主键对应 -->
        <id name="deptno" column="deptno">
            <!-- 主键生成策略的类型:放弃对主键的管理,要求程序手动添加-->
            <generator class="assigned"/>
        </id>

        <!-- 建立类中的普通的属性和表的字段的对应 -->
        <property name="dname" column="dname"/>
        <property name="loc" column="loc"/>

        <!-- 配置一对多的映射:这里是Dept,一个Dept有多个Emp,在这里配置Emp集合 -->
        <!--
            set标签:
                name:Dept类中集合属性的名称
                cascade:级联操作类型
                inverse:放弃外键管理
        -->
        <set name="emps" cascade="save-update,delete" inverse="true">
            <!-- 多的一方,表外键的名称 -->
            <key column="deptno"/>
            <!-- 多的一方,类的全路径 -->
            <one-to-many class="com.pipi.hibernate03.Emp"/>
        </set>

    </class>
</hibernate-mapping>

Emp类映射emp表:Emp.hbm.xml映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- 建立类与表的映射 -->
    <class name="com.pipi.hibernate03.Emp" table="emp">

        <!-- 建立类中的OID与表中的主键对应 -->
        <id name="empno" column="empno" >
            <!-- 主键生成策略的类型 -->
            <generator class="native"/>
        </id>

        <!-- 建立类中的普通的属性和表的字段的对应 -->
        <property name="ename" column="ename" />
        <property name="job" column="job" />
        <property name="mgr" column="mgr" />
        <property name="hiredate" column="hiredate" />
        <property name="sal" column="sal" />
        <property name="comm" column="comm" />

        <!-- 配置多对一的映射:这里是Emp,而一个Emp只能属于一个Dept,在这里配置一个Dept-->
        <!--
            many-to-one标签:
                name:Emp类中部门属性的名称
                class:Dept类的全路径
                column:emp表中的外键名称
        -->
        <many-to-one name="dept" cascade="save-update" class="com.pipi.hibernate03.Dept" column="deptno"/>

    </class>
</hibernate-mapping>

(4)编写核心配置文件

命名只能为:hibernate.cfg.xml,建议直接放在src下。

<?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>

		<!-- 连接数据库的基本参数 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate_one_to_many</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">123456</property>

		<!-- 配置Hibernate的方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

		<!-- 可选配置================ -->
		<!-- 打印SQL -->
		<property name="hibernate.show_sql">true</property>
		<!-- 格式化SQL -->
		<property name="hibernate.format_sql">true</property>
		<!-- 自动创建表 -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		
		<!-- 配置C3P0连接池 -->
		<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
		<!--在连接池中可用的数据库连接的最少数目 -->
		<property name="c3p0.min_size">5</property>
		<!--在连接池中所有数据库连接的最大数目  -->
		<property name="c3p0.max_size">20</property>
		<!--设定数据库连接的过期时间,以秒为单位,
		如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
		<property name="c3p0.timeout">120</property>
		 <!--每3000秒检查所有连接池中的空闲连接,以秒为单位-->
		<property name="c3p0.idle_test_period">3000</property>

		<!-- 设置事务的隔离级别,MySQL默认是4,即可重复读 -->
		<property name="hibernate.connection.isolation">4</property>

		<!-- 配置当前线程绑定的事务 -->
		<property name="hibernate.current_session_context_class">thread</property>

		<!--绑定映射文件,一对多关系,绑定2个映射文件-->
		<mapping resource="dirs/Emp.hbm.xml"/>
		<mapping resource="dirs/Dept.hbm.xml"/>

	</session-factory>
</hibernate-configuration>

(5)编写测试类

测试代码:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

// 编写测试类,测试一对多是否配置成功
public class Test01 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 创建2个员工
        Emp emp1 = new Emp();
        emp1.setEname("张三");
        Emp emp2 = new Emp();
        emp2.setEname("李四");

        // 创建1个部门
        Dept dept = new Dept(50, "皮皮部门", "北京");

        // 将员工和部门产生关联:设置双向关联
        emp1.setDept(dept);
        emp2.setDept(dept);
        dept.getEmps().add(emp1);
        dept.getEmps().add(emp2);

		// 在没有配置级联属性情况下
        // 保存到数据库中,必须保存创建的所有对象,不然会出现:瞬时态对象异常
        session.save(emp1);
        session.save(emp2);
        session.save(dept);

        transaction.commit();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值