Java的Hibernate框架中的組合映射學(xué)習(xí)教程
一、組合映射
組合是關(guān)聯(lián)關(guān)系的一種特殊情況,是關(guān)聯(lián)關(guān)系耦合度最高的一種關(guān)系,組合的主對(duì)象和子對(duì)象擁有相同的生命周期,主對(duì)像消亡的話(huà)子對(duì)象也會(huì)消亡。這里使用雇主和用戶(hù)作為示例,用戶(hù)和雇主都擁有聯(lián)系方式屬性,如果這里站在對(duì)象角度思考的話(huà),常常會(huì)把對(duì)象模型繪制成為組合的方式,抽象出來(lái)一個(gè)共同的聯(lián)系方式類(lèi),然后兩種人分別包含相應(yīng)的聯(lián)系方式對(duì)象即可,向應(yīng)的對(duì)象模型時(shí)它的對(duì)象示例如下圖所示:

組合對(duì)象模型在生成相應(yīng)的關(guān)系模型后會(huì)把對(duì)應(yīng)的子類(lèi)包含到主表中,所以對(duì)應(yīng)的表結(jié)構(gòu)會(huì)將相應(yīng)的屬性生成到對(duì)應(yīng)的表中,相應(yīng)的表結(jié)構(gòu)如下:

1.1 Employee類(lèi)及映射文件
在對(duì)象模型中Employee和Contact之間擁有包含關(guān)系,在編寫(xiě)代碼時(shí)需要將Contact對(duì)象包含在Employee中。對(duì)應(yīng)的映射文件中也需要有Contact對(duì)象的映射,需要使用<component>標(biāo)簽來(lái)標(biāo)明組合的對(duì)象,并把對(duì)象的屬性添加到對(duì)象標(biāo)簽中。
清單一:Employee.java,類(lèi)文件中除了基本的屬性外還需要分裝Contact對(duì)象,因?yàn)樗鼈冎g有一層包含關(guān)系。
package com.src.hibernate;
public class Employee {
//id號(hào)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//名稱(chēng)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//聯(lián)系對(duì)象
private Contact userContact;
public Contact getUserContact() {
return userContact;
}
public void setUserContact(Contact userContact) {
this.userContact = userContact;
}
}
清單二:Employee.hbm.xml,添加對(duì)應(yīng)的映射文件,映射的組合對(duì)象要使用<component>來(lái)標(biāo)明,并在該標(biāo)簽中添加對(duì)應(yīng)的對(duì)象屬性,具體如下代碼:
<?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類(lèi)及配置文件
清單三:User.java,它的內(nèi)容結(jié)構(gòu)和Employee.java的相同,其它的不再多說(shuō),看代碼:
package com.src.hibernate;
public class User {
//id號(hào)
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;
}
//聯(lián)系對(duì)象
private Contact userContact;
public Contact getUserContact() {
return userContact;
}
public void setUserContact(Contact userContact) {
this.userContact = userContact;
}
}
清單四:User.hbm.xml,它的內(nèi)容結(jié)構(gòu)同Employee.hbm.xml內(nèi)容,主要是<component>標(biāo)簽的使用,很簡(jiǎn)單,代碼如下:
<?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類(lèi)
該類(lèi)文件沒(méi)有什么需要注意的地方,添加基本的屬性即可,也不需要為該類(lèi)配置對(duì)應(yīng)的映射,所以它的內(nèi)容相當(dāng)?shù)暮?jiǎn)單。
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;
}
//郵編號(hào)
private String zipCode;
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
//聯(lián)系電話(huà)
private String contactTel;
public String getContactTel() {
return contactTel;
}
public void setContactTel(String contactTel) {
this.contactTel = contactTel;
}
}
1.4 生成結(jié)果
經(jīng)過(guò)上面的文件配置后接下來(lái)就可以生成相應(yīng)的數(shù)據(jù)庫(kù)表結(jié)構(gòu)了,生成的SQL語(yǔ)句如下:
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))
生成的數(shù)據(jù)庫(kù)表結(jié)構(gòu)如下:

二、數(shù)據(jù)操作
組合映射得到的表結(jié)構(gòu)是一個(gè)完整的表,所以在寫(xiě)入和讀取數(shù)據(jù)時(shí)采用最原始的方法就可以實(shí)現(xiàn),這里還使用前幾篇文章中用到的測(cè)試方法來(lái)寫(xiě)入和讀取數(shù)據(jù),分別是使用save和load方法,具體操作見(jiàn)下文。
2.1 插入數(shù)據(jù)
這里使用User作為示例,Employee的寫(xiě)入操作同User。在寫(xiě)入數(shù)據(jù)時(shí)需要?jiǎng)?chuàng)建兩個(gè)對(duì)象,一個(gè)是聯(lián)系對(duì)象,另外一個(gè)是用戶(hù)對(duì)象,在保存時(shí)只需要保存用戶(hù)對(duì)象即可,相應(yīng)的聯(lián)系對(duì)象會(huì)連帶著保存。
public void testSave1(){
//聲明會(huì)話(huà)對(duì)象
Session session=null;
try{
//獲取會(huì)話(huà)對(duì)象
session=HibernateUtils.getSession();
//開(kāi)啟會(huì)話(huà)
session.beginTransaction();
//創(chuàng)建連接對(duì)象
Contact userContact=new Contact();
userContact.setAddress("北京市");
userContact.setContactTel("1243435");
userContact.setEmail("123@gamil.com");
userContact.setZipCode("zipCode");
//創(chuàng)建用戶(hù)對(duì)象
User user=new User();
user.setName("zhangsan");
user.setUserContact(userContact);
session.save(user);
//提交會(huì)話(huà)
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
生成的SQL語(yǔ)句:
insert into t_user (name, email, address, zipCode, contactTel) values (?, ?, ?, ?, ?)
查看表結(jié)構(gòu)如下:

2.2讀取操作
同樣使用User作為示例,Employee的操作同User對(duì)象。讀取操作相當(dāng)?shù)暮?jiǎn)單,代碼如下:
public void testLoad1(){
//聲明會(huì)話(huà)對(duì)象
Session session=null;
try{
//獲取會(huì)話(huà)對(duì)象
session=HibernateUtils.getSession();
//開(kāi)啟會(huì)話(huà)
session.beginTransaction();
//獲取user對(duì)象
User user=(User)session.load(User.class, 1);
System.out.println("用戶(hù)姓名: "+user.getName());
//提交會(huì)話(huà)
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
生成對(duì)應(yīng)的結(jié)果如下:
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=? 用戶(hù)姓名: zhangsan
三、綜合實(shí)例
Account:
public class Account implements Serializable{
private int id;
private double money;
private Address address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address:
public class Address implements Serializable{
private String code;
private String city;
private String province;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
Account.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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="pojo">
<class name="Account" table="t_account" >
<id name="id">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="money">
<column name="money"></column>
</property>
<component name="address">
<property name="code">
<column name="code"></column>
</property>
<property name="city">
<column name="city"></column>
</property>
<property name="province">
<column name="province"></column>
</property>
</component>
</class>
</hibernate-mapping>
相關(guān)文章
Java中正則表達(dá)式匹配過(guò)程實(shí)例詳解
正則匹配即是在給定字符串中查找符合正則表達(dá)式的字符,下面這篇文章主要給大家介紹了關(guān)于Java中正則表達(dá)式匹配過(guò)程的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10
使用eclipse 實(shí)現(xiàn)將springboot項(xiàng)目打成jar包
這篇文章主要介紹了使用eclipse 實(shí)現(xiàn)將springboot項(xiàng)目打成jar包的流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java timezone設(shè)置和mybatis連接數(shù)據(jù)庫(kù)時(shí)區(qū)設(shè)置方式
這篇文章主要介紹了Java timezone設(shè)置和mybatis連接數(shù)據(jù)庫(kù)時(shí)區(qū)設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
IDEA 顯示Run Dashboard窗口的2種方式(推薦)
這篇文章主要介紹了IDEA 顯示Run Dashboard窗口的2種方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
java 使用線(xiàn)程做的一個(gè)簡(jiǎn)單的ATM存取款實(shí)例代碼
線(xiàn)程 Thread 類(lèi),和 Runable 接口 比較兩者的特點(diǎn)和應(yīng)用領(lǐng)域.可以,直接繼承線(xiàn)程Thread類(lèi)。該方法編寫(xiě)簡(jiǎn)單,可以直接操作線(xiàn)程,適用于單重繼承情況,因而不能在繼承其他類(lèi),下面我們來(lái)看一個(gè)實(shí)例2013-08-08
SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例
這篇文章主要介紹了SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

