【Hibernate步步为营】--组合映射详解

上篇文章详细讨论了复合主键的映射原理,对于复合主键映射需要使用<composite-id>标签来标明映射的类属性,并在该标签中添加<key-property>子标签,并且主键列需要实现序列化接口,使用很简单只要学会如何进行映射就可以实现复合映射。接下来讨论组合对象映射,组合映射关系其实是把两个对象的公共部分抽象出来形成一个对象,两个子对象会包含另一个主对像,在配置映射文件时需要使用<component>标签来标明映射关系。

一、组合映射

组合是关联关系的一种特殊情况,是关联关系耦合度最高的一种关系,组合的主对象和子对象拥有相同的生命周期,主对像消亡的话子对象也会消亡。这里使用雇主和用户作为示例,用户和雇主都拥有联系方式属性,如果这里站在对象角度思考的话,常常会把对象模型绘制成为组合的方式,抽象出来一个共同的联系方式类,然后两种人分别包含相应的联系方式对象即可,向应的对象模型时它的对象示例如下图所示:

组合对象模型在生成相应的关系模型后会把对应的子类包含到主表中,所以对应的表结构会将相应的属性生成到对应的表中,相应的表结构如下:

1.1 Employee类及映射文件

在对象模型中Employee和Contact之间拥有包含关系,在编写代码时需要将Contact对象包含在Employee中。对应的映射文件中也需要有Contact对象的映射,需要使用<component>标签来标明组合的对象,并把对象的属性添加到对象标签中。

清单一:Employee.java,类文件中除了基本的属性外还需要分装Contact对象,因为它们之间有一层包含关系。

package com.src.hibernate;

public class Employee {
	//id号
	private int id;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	//名称
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	//联系对象
	private Contact userContact;
	public Contact getUserContact() {
		return userContact;
	}
	public void setUserContact(Contact userContact) {
		this.userContact = userContact;
	}

}

清单二:Employee.hbm.xml,添加对应的映射文件,映射的组合对象要使用<component>来标明,并在该标签中添加对应的对象属性,具体如下代码:

<?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.src.hibernate.Employee" table="t_employee">
		<id name="id">
			<generator class="native"/>
		</id>

		<property name="name"/>
		<component name="employeeContact">
			<property name="email"/>
			<property name="address"/>
			<property name="zipCode"/>
			<property name="contactTel"/>
		</component>
	</class>
</hibernate-mapping>

1.2 User类及配置文件

清单三:User.java,它的内容结构和Employee.java的相同,其它的不再多说,看代码:

<pre name="code" class="java">package com.src.hibernate;

public class User {
	//id号
	private int id;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	//姓名
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	//联系对象
	private Contact userContact;
	public Contact getUserContact() {
		return userContact;
	}
	public void setUserContact(Contact userContact) {
		this.userContact = userContact;
	}

}

清单四:User.hbm.xml,它的内容结构同Employee.hbm.xml内容,主要是<component>标签的使用,很简单,代码如下:

<?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.src.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native"/>
		</id>

		<property name="name"/>
		<component name="userContact">
			<property name="email"/>
			<property name="address"/>
			<property name="zipCode"/>
			<property name="contactTel"/>
		</component>
	</class>
</hibernate-mapping>

1.3 Contact.java类

该类文件没有什么需要注意的地方,添加基本的属性即可,也不需要为该类配置对应的映射,所以它的内容相当的简单。

package com.src.hibernate;

public class Contact {

	//email地址
	private String email;
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}

	//住址
	private String address;
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}

	//邮编号
	private String zipCode;
	public String getZipCode() {
		return zipCode;
	}
	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	//联系电话
	private String contactTel;
	public String getContactTel() {
		return contactTel;
	}
	public void setContactTel(String contactTel) {
		this.contactTel = contactTel;
	}
}

1.4  生成结果

经过上面的文件配置后接下来就可以生成相应的数据库表结构了,生成的SQL语句如下:

drop table if exists t_employee
drop table if exists t_user
create table t_employee (id integer not null auto_increment, name varchar(255), email varchar(255), address varchar(255), zipCode varchar(255), contactTel varchar(255), primary key (id))
create table t_user (id integer not null auto_increment, name varchar(255), email varchar(255), address varchar(255), zipCode varchar(255), contactTel varchar(255), primary key (id))

生成的数据库表结构如下:

二、数据操作

组合映射得到的表结构是一个完整的表,所以在写入和读取数据时采用最原始的方法就可以实现,这里还使用前几篇文章中用到的测试方法来写入和读取数据,分别是使用save和load方法,具体操作见下文。

2.1 插入数据

这里使用User作为示例,Employee的写入操作同User。在写入数据时需要创建两个对象,一个是联系对象,另外一个是用户对象,在保存时只需要保存用户对象即可,相应的联系对象会连带着保存。

public void testSave1(){
	//声明会话对象
	Session session=null;

	try{
		//获取会话对象
		session=HibernateUtils.getSession();
		//开启会话
		session.beginTransaction();

		//创建连接对象
		Contact userContact=new Contact();
		userContact.setAddress("北京市");
		userContact.setContactTel("1243435");
		userContact.setEmail("[email protected]");
		userContact.setZipCode("zipCode");

		//创建用户对象
		User user=new User();
		user.setName("zhangsan");
		user.setUserContact(userContact);

		session.save(user);
		//提交会话
		session.getTransaction().commit();
	}catch(Exception e){
		e.printStackTrace();
		session.getTransaction().rollback();
	}finally{
		HibernateUtils.closeSession(session);
	}
}

生成的SQL语句:

insert into t_user (name, email, address, zipCode, contactTel) values (?, ?, ?, ?, ?)

查看表结构如下:

2.2读取操作

同样使用User作为示例,Employee的操作同User对象。读取操作相当的简单,代码如下:

public void testLoad1(){
	//声明会话对象
	Session session=null;

	try{
		//获取会话对象
		session=HibernateUtils.getSession();
		//开启会话
		session.beginTransaction();

		//获取user对象
		User user=(User)session.load(User.class, 1);

		System.out.println("用户姓名: "+user.getName());
		//提交会话
		session.getTransaction().commit();
	}catch(Exception e){
		e.printStackTrace();
		session.getTransaction().rollback();
	}finally{
		HibernateUtils.closeSession(session);
	}
}

生成对应的结果如下:

Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.email as email0_0_, user0_.address as address0_0_, user0_.zipCode as zipCode0_0_, user0_.contactTel as contactTel0_0_ from t_user user0_ where user0_.id=?
用户姓名: zhangsan

结语

组合映射需要使用<component>标签,在该标签中添加需要包含的对象,然后Hibernate会把它生成相应的关系模型,相应的写入数据和读取数据的操作也会很简单。组合映射就介绍到这里,下篇文章将会讨论最后一种映射--集合映射。

【Hibernate步步为营】--组合映射详解,布布扣,bubuko.com

时间: 2024-10-15 02:01:36

【Hibernate步步为营】--组合映射详解的相关文章

hibernate 表关系映射详解之一对多

一对多 传统模式:jdbc连接数据库的传统模式下,是通过主键连接外键实现一对多关系的映射, 其数据库中表的对应关系是在多方加入一方的主键,而后形成外键连接. Hibernate:引入hibernate框架后,通过类的形式来表示一对多的关系. 举例:订单与订单详细的关系,一个订单包含多个商品,多个商品属于一个订单,两者的关系是一对多的关系. 实现原理: 面向对象实现------ 在order类中加入item类的set集合 ,表示在订单类中包含有多个订单详细(集合表示). 层次结构: 步骤一:编写实

hibernate 表关系映射详解之一对一

举例:用户和邮箱的关系,一个用户拥有一个邮箱,一个邮箱属于一个用户 关系图: 实现原理:因为两者皆是一方,无论在那一方加入,都可实现单项映射. 配置文件: 结构图: 实体类: hibernate实现映射一对一中有两种方法. 方法一(通过多对一映射): 步骤一: 在Customer类中加入Email类 步骤二:配置customer类的映射文件  -- > Customer.hbm.xml 本来多对一的映射,加入unique(唯一)之后,就很巧妙的变成一对一的映射,网上说这样的拓展性很好,没试过,这

hibernate 表关系映射详解之继承关系

举例:亚马逊的网上商城可以卖很多东西,比如说图书,电器,水果等等,那么我们以面向对象的理念去抽象一个商品类,他具有商品的共有属性,比如说上架时间,当前         价格,优惠价格等待,商品可以继承商品类,也可以保有自己的属性,比如说商品名等等.这种关系称为继承. 上文说到继承,那么怎么在数据库中体现继承,以及在hibernate实现继承. 数据库表中体现继承,可以先创建一个商品类表,然后创建一个商品表(类型不定),他们之间拥有同样的主键建立联系. 表结构: 如何在hibernate中实现继承

Hibernate学习(五)———— hibernate一对一关系映射详解

一.一对一关系的概述 一对一关系看起来简单,其实也挺复杂的.其中关系就包含了四种,单向双向和主键关联外键关联. 什么意思呢,也就是包含了单向一对一主键关联.双向一对一主键关联,单向一对一外键关联,双向一对一外键关联, 这四种中,单双向就不用在说了把,就是看你业务需求来去设置是否是单双向,而外键关联也很简单,前面的一对多和多对多度是依靠外键关联关系来写的.那主键关联关系是怎么样的呢?其实跟外键关联差不多,唯一的区别就是,让一个类的主键当作外键使用来指向另一个关联类的主键,从而两个类的主键就达到了同

hibernate(五) hibernate一对一关系映射详解

序言 之前讲解了一对多(单向.双向).多对多(双向),今天就讲解一下最后一个关系,一对一. 心情不错.状态也挺好的,赶紧写一篇博文造福一下大家把. --WZY 一.一对一关系的概述 一对一关系看起来简单,其实也挺复杂的.其中关系就包含了四种,单向双向和主键关联外键关联. 什么意思呢,也就是包含了单向一对一主键关联.双向一对一主键关联,单向一对一外键关联,双向一对一外键关联, 这四种中,单双向就不用在说了把,就是看你业务需求来去设置是否是单双向,而外键关联也很简单,前面的一对多和多对多度是依靠外键

hibernate 表关系映射详解之多对多

举例:商品类型表与商品表,每种类型对应多个商品,每个商品对应多种类型 关系图: hirbernate实现多对多映射有两种方法,第一种是通过中间表直接映射,第二种是通过中间表间接映射. 直接映射: 配置实体类(因为都是多对多的关系,所以双方都具有set集合): 配置实体类的映射文件: 分析:category类先通过category_Id与中间表tb_category_product建立联系,然后再通过多对多标签中的porduct_id与product类建立多对多联系. product类同上类似.

【Hibernate步步为营】--多对多映射详解

上篇文章详细讨论了一对多映射,在一对多映射中单向的关联映射会有很多问题,所以不建议使用如果非要采用一对多的映射的话可以考虑使用双向关联来优化之间的关系,一对多的映射其实质上是在一的一端使用<many-to-one>标签来标明它们之间的关系,另外还需要在一的一端的对象中使用set标明集合映射. 一.单向多对多 仍然按照前几篇的文章格式来讨论,首先来看对象之间的关系,单向的多对多关系是两个对象之间发生的,比如在人和职位之间,一个人可以有多个职位,而且一个职位也可以由多人来负责,所以它们之间就形成了

【Hibernate步步为营】--双向关联一对一映射详解(二)

很不好意思,有两天时间没有更新博客文章了,不写文章的日子还真是感觉很空洞啊,养成了写文章的恶习想改也改不掉啊.说点题外话,前两天收到一位朋友的私信,邀请笔者写一篇有关OWS的文章,用来研究图标工具的一种技术,很荣幸收到这位朋友的邀请,但是因为这几天开发的项目着急上线所以暂时没有时间去研究,只能等这周末了,利用周末的时间来研究然后更新类似的技术文章. 回到文章的正题,上篇文章讨论了双向主键关联,它其实是一对一主键关联的一种特殊情况,想要实现双向的关联就必须在映射文件的两端同时配置<one-to-o

【Hibernate步步为营】--继承映射详解

上篇文章讨论了多对多映射,在使用多对多映射时重点是使用<many-to-many>标签,并在标签的两端加入外键这样在生成关系时会创建两个关系之间的关系表,通过关系表来维护它们之间的关系,另外对于单向和双向的区别是在映射的哪一端添加标签的问题.在面向对象中很重要的一个特性就是继承,继承实现了代码的复用,而且Hibernate把基本上所有的对象模型进行了映射封装,其中就包括继承映射,接下来就详细讨论. 一.继承映射 继承是面向对象很重要的特性,它实现了代码的服用,在关系模型中同样也有继承关系,这种