hibernate 1-1(详解)

域模型

关系数据模型:

  • 按照外键映射:

  • 按照主键映射:

基于外键映射的 1-1

  • 对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加many-to-one元素。为many-to-one元素增加unique=“true” 属性来表示为1-1关联

  • 另一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段

-不使用 property-ref 属性的 sql

-使用 property-ref 属性的 sql

为什么不两边都使用外键映射的 1-1

这样就不是一对一关系映射了。

基于主键映射的 1-1

  • 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”
  • 采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其one-to-one属性还应增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。
  • constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象(“对方”)所对应的数据库表主键

基于外键映射的 1-1

实例详解:

Department.java

package com.atguigu.hibernate.one2one.foreign;

public class Department {

	private Integer deptId;
	private String deptName;

	private Manager mgr;

	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;
	}

	public Manager getMgr() {
		return mgr;
	}

	public void setMgr(Manager mgr) {
		this.mgr = mgr;
	}

}

Manager.java

package com.atguigu.hibernate.one2one.foreign;

public class Manager {

	private Integer mgrId;
	private String mgrName;

	private Department dept;

	public Integer getMgrId() {
		return mgrId;
	}

	public void setMgrId(Integer mgrId) {
		this.mgrId = mgrId;
	}

	public String getMgrName() {
		return mgrName;
	}

	public void setMgrName(String mgrName) {
		this.mgrName = mgrName;
	}

	public Department getDept() {
		return dept;
	}

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

}

Department.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.atguigu.hibernate.one2one.foreign.Department" table="DEPARTMENTS">

        <id name="deptId" type="java.lang.Integer">
            <column name="DEPT_ID" />
            <generator class="native" />
        </id>

        <property name="deptName" type="java.lang.String">
            <column name="DEPT_NAME" />
        </property>

		<!-- 使用 many-to-one 的方式来映射 1-1 关联关系 -->
		<many-to-one name="mgr" class="com.atguigu.hibernate.one2one.foreign.Manager"
			column="MGR_ID" unique="true"></many-to-one>	        

    </class>
</hibernate-mapping>

Manager.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="com.atguigu.hibernate.one2one.foreign.Manager" table="MANAGERS">

        <id name="mgrId" type="java.lang.Integer">
            <column name="MGR_ID" />
            <generator class="native" />
        </id>

        <property name="mgrName" type="java.lang.String">
            <column name="MGR_NAME" />
        </property>

        <!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 -->
        <!--
        	没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
         -->
        <one-to-one name="dept"
        	class="com.atguigu.hibernate.one2one.foreign.Department"
        	property-ref="mgr"></one-to-one>

    </class>

</hibernate-mapping>
package com.atguigu.hibernate.one2one.foreign;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class HibernateTest {

	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;

	@Before
	public void init(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry =
				new ServiceRegistryBuilder().applySettings(configuration.getProperties())
				                            .buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);

		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}

	@After
	public void destroy(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	@Test
	public void testGet2(){
		//在查询没有外键的实体对象时, 使用的左外连接查询, 一并查询出其关联的对象
		//并已经进行初始化.
		Manager mgr = (Manager) session.get(Manager.class, 1);
		System.out.println(mgr.getMgrName());
		System.out.println(mgr.getDept().getDeptName());
	}

	@Test
	public void testGet(){
		//1. 默认情况下对关联属性使用懒加载
		Department dept = (Department) session.get(Department.class, 1);
		System.out.println(dept.getDeptName()); 

		//2. 所以会出现懒加载异常的问题.
//		session.close();
//		Manager mgr = dept.getMgr();
//		System.out.println(mgr.getClass());
//		System.out.println(mgr.getMgrName()); 

		//3. 查询 Manager 对象的连接条件应该是 dept.manager_id = mgr.manager_id
		//而不应该是 dept.dept_id = mgr.manager_id
		Manager mgr = dept.getMgr();
		System.out.println(mgr.getMgrName()); 

	}

	@Test
	public void testSave(){

		Department department = new Department();
		department.setDeptName("DEPT-BB");

		Manager manager = new Manager();
		manager.setMgrName("MGR-BB");

		//设定关联关系
		department.setMgr(manager);
		manager.setDept(department);

		//保存操作
		//建议先保存没有外键列的那个对象. 这样会减少 UPDATE 语句
		session.save(department);
		session.save(manager);

	}

}

基于主键映射的 1-1

实例详解:

实体类不变和上面相同

Department.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.atguigu.hibernate.one2one.primary">

    <class name="Department" table="DEPARTMENTS">

        <id name="deptId" type="java.lang.Integer">
            <column name="DEPT_ID" />
            <!-- 使用外键的方式来生成当前的主键 -->
            <generator class="foreign">
            	<!-- property 属性指定使用当前持久化类的哪一个属性的主键作为外键 -->
            	<param name="property">mgr</param>
            </generator>
        </id>

        <property name="deptName" type="java.lang.String">
            <column name="DEPT_NAME" />
        </property>

		<!--
		采用 foreign 主键生成器策略的一端增加 one-to-one 元素映射关联属性,
		其 one-to-one 节点还应增加 constrained=true 属性, 以使当前的主键上添加外键约束
		-->
		<one-to-one name="mgr" class="Manager" constrained="true"></one-to-one>

    </class>
</hibernate-mapping>

Manager.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="com.atguigu.hibernate.one2one.primary.Manager" table="MANAGERS">

        <id name="mgrId" type="java.lang.Integer">
            <column name="MGR_ID" />
            <generator class="native" />
        </id>

        <property name="mgrName" type="java.lang.String">
            <column name="MGR_NAME" />
        </property>

        <one-to-one name="dept"
        	class="com.atguigu.hibernate.one2one.primary.Department"></one-to-one>

    </class>

</hibernate-mapping>
package com.atguigu.hibernate.one2one.primary;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class HibernateTest {

	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;

	@Before
	public void init(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry =
				new ServiceRegistryBuilder().applySettings(configuration.getProperties())
				                            .buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);

		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}

	@After
	public void destroy(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	@Test
	public void testGet2(){
		//在查询没有外键的实体对象时, 使用的左外连接查询, 一并查询出其关联的对象
		//并已经进行初始化.
		Manager mgr = (Manager) session.get(Manager.class, 1);
		System.out.println(mgr.getMgrName());
		System.out.println(mgr.getDept().getDeptName());
	}

	@Test
	public void testGet(){
		//1. 默认情况下对关联属性使用懒加载
		Department dept = (Department) session.get(Department.class, 1);
		System.out.println(dept.getDeptName()); 

		//2. 所以会出现懒加载异常的问题.
		Manager mgr = dept.getMgr();
		System.out.println(mgr.getMgrName());
	}

	@Test
	public void testSave(){

		Department department = new Department();
		department.setDeptName("DEPT-DD");

		Manager manager = new Manager();
		manager.setMgrName("MGR-DD");

		//设定关联关系
		manager.setDept(department);
		department.setMgr(manager);

		//保存操作
		//先插入哪一个都不会有多余的 UPDATE
		session.save(department);
		session.save(manager);

	}
}

hibernate 1-1(详解),布布扣,bubuko.com

时间: 2024-08-05 15:25:08

hibernate 1-1(详解)的相关文章

hibernate enum映射详解

hibernate enum映射详解 在这里介绍注解的形式,如果想要了解XML配置的方式,可以自行查找相关资料. 例如以下Entity @Entity @Table(name = "t_user") public class User implements Serializable { /** * */ private static final long serialVersionUID = -9042615274714038279L; @Id @GeneratedValue(stra

Hibernate fetch属性详解

主要参考 :http://4045060.blog.51cto.com/4035060/1088025 一.hibernate抓取策略(单端代理的批量抓取fetch=select(默认)/join) 1)保持默认,同fetch="select" <many-to-one name="group" column="group_id" fetch="select" /> 另外发送一条select语句抓取当前对象关联实体

Hibernate延迟加载机制详解

摘自 http://blog.chinaunix.net/uid-20577907-id-3129234.html 1 延迟加载: 延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作. 在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载.下面我们就分别介绍这些种类的延迟加载的细节. A.实体对象的延迟加载: 如果想对实体对象使用延迟加载,必须要在实体的映射配置文

【Hibernate步步为营】--详解基本映射

Hibernate进行了分类整合发现其实Hibernate分为三大部分:核心对象.映射.HQL,这三大部分开发过程中最常使用,前几篇讨论了核心对象及对象之间的转换方法,接下来讨论Hibernate的映射使用方法. 一.基本用法 Hibernate一个重要的功能就是映射,它能够在对象模型和关系模型之间转换,是面向对象编程思想提倡使用的,使用映射程序开发人员只需要关心对象模型中代码的编写.对象和关系数据库之间的映射通常是由XML文档来定义的.这个映射文档被设计为易读的,并且可以手动修改.这种映射关系

Hibernate 映射文件详解

Hibernate 映射文件详解 2010-09-02 19:03:33|  分类: Hibernate学习|举报|字号 订阅 Hibernate的持久化类和关系数据库之间的映射通常是用一个XML文档来定义的.该文档通过一系列XML元素的配置,来将持久化类与数据库表之间建立起一一映射.这意味着映射文档是按照持久化类的定义来创建的,而不是表的定义. 一.根元素:<hibernate-mapping>,每一个hbm.xml文件都有唯一的一个根元素,包含一些可选的属性 1)package:指定一个包

(转)Hibernate的配置详解

http://blog.csdn.net/yerenyuan_pku/article/details/65041077 在<Hibernate快速入门>一文中,我有讲到Hibernate的两个配置文件,今天就来详细地介绍这两个配置文件. Hibernate的配置详解 在Hibernate中,我们使用时主要有两种配置文件: 核心配置文件——hibernate.cfg.xml(主要描述Hibernate的相关配置) 映射配置文件——xxx.hbm.xml 核心配置文件 Hibernate的核心配置

Hibernate Session &amp; Transaction详解

Hibernate Session & Transaction详解 HIbernate中的Session Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持久化操作核心API, 注意这里的Session的含义,它与传统意思上web层的HttpSession并没有关系,Hibernate Session之与Hibernate,相当于JDBC Connection相对与JDBC. Session对象是有生命周期的,它以Transaction对象的事务开始和结束边界

【框架】[Hibernate]构架知识点详解入门与测试实例

转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] Hibernate介绍: Hibernate是一个开放源码的.非常优秀.成熟的O/R Mapping框架.它提供了强大.高性能的Java对象和关系数据的持久化和查询功能. O/R Mapping 对象关系映射(Object Relational Mapping,简称ORM)技术,是通过使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据库中. 对象和关系

Struts+Spring+Hibernate整合入门详解

标签: strutshibernatespringbeanactionimport 2007-08-12 16:05 36280人阅读 评论(13) 收藏 举报 分类: STRUTS&SPRING&HIBERNATE(12) Java 5.0 Struts 2.0.9 spring 2.0.6 hibernate 3.2.4 作者:  Liu Liu 转载请注明出处 基本概念和典型实用例子. 一.基本概念       Struts:作为基于 MVC 模式的 Web 应用最经典框架,两个项目

Hibernate之缓存详解

hibernate中提供了两级缓存,一级缓存是Session级别的缓存,它属于事务范围的缓存,该级缓存由hibernate管理,应用程序无需干预:二级缓存是SessionFactory级别的缓存,该级缓存可以进行配置和更改,并且可以动态加载和卸载,hibernate还为查询结果提供了一个查询缓存,它依赖于二级缓存: 一,缓存的概念 缓存是位于应用程序和永久性数据存储源之间用于临时存放复制数据的内存区域,缓存可以降低应用程序之间读写永久性数据存储源的次数,从而提高应用程序的运行性能: hibern