一:复合主键

复合主键即两个或多个字段联合起来作为主键,它的通常做法是将主键相关字段抽取出来放到一个单独的类中,但是这样的类是有要求的:

1.      必须实现序列化接口

2.      必须覆盖equals和hashCode方法

以会计核算期中核算年和核算月做主键为例,将这两个主键相关字段放到FiscalYearPeriodPK类中,代码如下:

package com.bjpowernode.hibernate;

import java.io.Serializable;

public class FiscalYearPeriodPK implements Serializable {

		//核算年
private int fiscalYear; //核算月
private int fiscalPeriod; public int getFiscalYear() {
return fiscalYear;
} public void setFiscalYear(int fiscalYear) {
this.fiscalYear = fiscalYear;
} public int getFiscalPeriod() {
return fiscalPeriod;
} public void setFiscalPeriod(int fiscalPeriod) {
this.fiscalPeriod = fiscalPeriod;
} //要实现序列化接口需要覆盖hashCode和equals方法,这样才能比较
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + fiscalPeriod;
result = prime * result + fiscalYear;
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FiscalYearPeriodPK other = (FiscalYearPeriodPK) obj;
if (fiscalPeriod != other.fiscalPeriod)
return false;
if (fiscalYear != other.fiscalYear)
return false;
return true;
}
}

持有该类引用的FiscalYearPeriod类代码如下:

package com.bjpowernode.hibernate;

import java.util.Date;

public class FiscalYearPeriod {

	private FiscalYearPeriodPK fiscalYearPeriodPK;

	//开始日期
private Date beginDate; //结束日期
private Date endDate; //状态
private String periodSts; public Date getBeginDate() {
return beginDate;
} public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
} public Date getEndDate() {
return endDate;
} public void setEndDate(Date endDate) {
this.endDate = endDate;
} public String getPeriodSts() {
return periodSts;
} public void setPeriodSts(String periodSts) {
this.periodSts = periodSts;
} public FiscalYearPeriodPK getFiscalYearPeriodPK() {
return fiscalYearPeriodPK;
} public void setFiscalYearPeriodPK(FiscalYearPeriodPK fiscalYearPeriodPK) {
this.fiscalYearPeriodPK = fiscalYearPeriodPK;
} }

来看最重要的部分,映射文件是如何进行配置的,在复合主键映射的配置中需要引入一个新的标签<composite-id>,这个标签的作用就是告诉Hibernate,生成的表使用的是复合主键,其中的<key>标签便是具体的联合主键字段,下面是映射文件内容:

<?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.bjpowernode.hibernate.FiscalYearPeriod" table="t_fiscal_year_period">
<composite-id name="fiscalYearPeriodPK">
<key-property name="fiscalYear"/>
<key-property name="fiscalPeriod"/>
</composite-id>
<property name="beginDate" type="date"/>
<property name="endDate" type="date"/>
<property name="periodSts"/>
</class>
</hibernate-mapping>

二:组合映射

采用组合映射的条件是由两个或多个类,他们持有多个相同的具有相同特点的成员变量(变量类型和名称一样),这时可以将这些相同的成员变量抽取出来放到另外一个类中,该类只是实体的一部分(注意这个类并不是实体类),与实体类相比它没有对象id,我们将其称之为值类。比如有User和Employee两个类,均持有  ,id,name,email,address,zipCode,contactTel属性,通过观察可知,后四个字段都属于通讯方面的信息,所以可以将这四个字段抽取出来放到类Contact中,然后让User和Employee类都持有Contact的引用即可,只要在映射文件中做好相应的配置,同样可以达到原来的映射效果。下面来看User.hbm.xml(Employee.hbm.xml与User.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>
<!-- User.hbm.xml文件 -->
<class name="com.bjpowernode.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> <!-- Employee.hbm.xml文件 -->
    <class name="com.bjpowernode.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>

通过上述配置同样可以达到每个类持有六个成员变量的效果,但是使用组合映射可以实现对象模型的细粒度划分,复用率高,含义明确,另外如果想要扩展属性的只要在抽取的类中进行扩展就可以,更加灵活。

步步为营Hibernate全攻略(四)剪不断理还乱之:复合主键 && 组合映射的更多相关文章

  1. 步步为营Hibernate全攻略(一)构建Hibernate框架环境

    任何一项新技术的出现都有它的必然性,Hibernate也不例外,所以在掌握Hibernate的具体应用之前我们一定先要了解Hibernate是什么?使用Hibernate会给我们的程序开发带来哪些好处 ...

  2. 【Hibernate步步为营】--复合主键映射具体解释

    上篇文章讨论了继承映射,它是对象模型中最主要的特性,对于继承映射它的主要区分是字段类型的不同,所以在生成表结构时须要有新列来标识数据的类型,能够使用<subclass>标签并在标签中加入d ...

  3. VSCode插件开发全攻略(四)命令、菜单、快捷键

    更多文章请戳VSCode插件开发全攻略系列目录导航. 命令 我们在前面HelloWord章节中已经提到了命令写法,这里再重温一下. context.subscriptions.push(vscode. ...

  4. Moon.Orm3.8技术全攻略

    Moon.ORM技术全攻略  一.绪论 本文主要是针对Moon.ORM的技术的讨论及其使用使用指导.如有其它疑问,请留言.本文主要针对Moon.ORM3.9版本,同时将会对4.0做一个技术预览.本文从 ...

  5. 取代奶瓶Minidwep-gtk破解WPA 全攻略

    取代奶瓶Minidwep-gtk 破 WPA 全攻略  目录 1. CDlinux 下使用 minidwepgtk 获取握手包并使用自带的字典破解 2. 自带的字典破解不出密码时使用 U 盘外挂字典继 ...

  6. 用C#制作PDF文件全攻略

    用C#制作PDF文件全攻略 目  录 前    言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...

  7. 【转】轻松搞定FTP之FlashFxp全攻略

    转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...

  8. Android-x86虚拟机安装配置全攻略

    转自Android-x86虚拟机安装配置全攻略 注:这里安装从简,具体请参考虚拟机Vmware安装运行安卓4.0详细教程 Android-x86虚拟机安装配置网上有很多,但是全部说明白的确不多,希望这 ...

  9. 【转载】Google Analytics 使用图文全攻略

    转载自:Google Analytics 使用图文全攻略 最近一段时间,因为工作的需要,小励使用GA(GA是Google Analytics的简称)比较频繁,所以花时间研究了一下,从不太了解到会使用( ...

随机推荐

  1. [HTML5游戏开发]简单的《找不同汉字版》,来考考你的眼力吧

    本次 游戏 开发需要用到lufylegend.js开源游戏引擎,版本我用的是1.5.2(现在最新的版本是1.6.0).    引擎下载的位置: http://lufylegend.googlecode ...

  2. Android基础总结(精华完整版)

    1. 前言 1.1. 什么是3G.4G Ÿ 第三代移动通信技术(3rd - Generation),速率一般在几百Kbps,较之前的2G和2.5G在数据传输速度上有很大提升. Ÿ 第四代移动通信技术( ...

  3. Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_3

    点击下载代码   http://download.csdn.net/detail/lideguo1979/8291803 新建一个类RouteNavigation,定义getPath()方法.用来获取 ...

  4. EF架构使用随机排序

    c#当中,可以用Random类来获取随机数 EF当中,我们写Linq时,抑或是采用Linq的扩展方法时,发现都没有随机排序的方法,这就要求我们自己去扩展了 引用自http://www.cnblogs. ...

  5. jetty插件配置(开发)

     <plugins>           <!-- jetty插件 -->           <plugin>               <groupId ...

  6. Swift - 委托(delegate)的介绍,及使用样例

    1,委托的说明 委托(delegate)是Cocoa的一个术语,表示将一个对象的部分功能转交给另一个对象. 比如对象A希望对象B知道将要发生或已经发生某件事情,对象A可以把对象B的引用存为一个实例变量 ...

  7. Oracle的序列

    Oracle的序列 序列介绍 序列是Oracle提供的用于产生一系列唯一数字的数据库对象. 使用序列能够实现自己主动产生主键值.序列也能够在很多用户并发环境中使用.为所实用户生成不反复的顺序数字,并且 ...

  8. RAD路线规划2016版

    http://community.embarcadero.com/article/news/16211-embarcadero-rad-studio-2016-product-approach-and ...

  9. 如何学习php之吐槽

    我也做了php一段时间了.从技术层面上解释吧.   深入学习任何的东西都要有个体系.   1 完整的学习整个体系结构.解决有什么的问题.   推荐看看这个.http://www.open-open.c ...

  10. JAVA中字符串比較equals()和equalsIgnoreCase()的差别

    .使用equals( )方法比較两个字符串是否相等.它具有例如以下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串(String)对象做比較的字符串 ...