主要分析三点:

一、数据表和Java类的映射 ;

二、单一主键映射和主键的生成策略 ;

三、复合主键的表映射 ;

一、数据表和Java类的映射 

Hibernate封装了数据库DDL语句,只需要将数据表和类之间实现映射,即可对数据表进行操作。

示例:数据库中存在表interface_admin.ds_area,实现表和类之间映射,其中单一主键oggKeyId,使用主键自动生成策略UUID,具体第二点进行阐述 。

package com.pec.model;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "interface_admin.ds_area")
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)
public class DsAreaModel implements Serializable {
private static final long serialVersionUID = 1L;
//电商平台代号(WS微商/CT村淘/TM天猫/JD京东)
private String comId ;
//行政省/直辖市代号
private String provinceId ;
//行政省/直辖市名称
private String provinceName ;
//地级市代号
private String cityId ;
//地级市名称
private String cityName ;
//行政区/县代号
private String regiId ;
//行政区/县名称
private String regiName ;
//创建时间
private Timestamp creatDate ;
//最后更新时间
private Timestamp lastUpdDate ;
//主键
private String oggKeyId ;
@Column(name = "com_id")
public String getComId() {
return comId;
}
public void setComId(String comId) {
this.comId = comId;
}
@Column(name = "province_id")
public String getProvinceId() {
return provinceId;
}
public void setProvinceId(String provinceId) {
this.provinceId = provinceId;
}
@Column(name = "province_nm")
public String getProvinceName() {
return provinceName;
}
public void setProvinceName(String provinceName) {
this.provinceName = provinceName;
}
@Column(name = "city_id")
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
@Column(name = "city_nm")
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
@Column(name = "regi_id")
public String getRegiId() {
return regiId;
}
public void setRegiId(String regiId) {
this.regiId = regiId;
}
@Column(name = "regi_nm")
public String getRegiName() {
return regiName;
}
public void setRegiName(String regiName) {
this.regiName = regiName;
}
@Column(name = "cre_date")
public Timestamp getCreatDate() {
return creatDate;
}
public void setCreatDate(Timestamp creatDate) {
this.creatDate = creatDate;
}
@Column(name = "last_upd_date")
public Timestamp getLastUpdDate() {
return lastUpdDate;
}
public void setLastUpdDate(Timestamp lastUpdDate) {
this.lastUpdDate = lastUpdDate;
}
@Id
@Column(name = "ogg_key_id", unique = true, nullable = false)
@GeneratedValue(generator = "systemUUID")
@GenericGenerator(name = "systemUUID", strategy = "uuid")
public String getOggKeyId() {
return oggKeyId;
}
public void setOggKeyId(String oggKeyId) {
this.oggKeyId = oggKeyId;
}
}

二、单一主键映射和主键的生成策略 

当数据表中只存在单一主键(大多数情况下都是单一主键),主键标识着一条记录,不可重复和为空,标志位唯一。但是此主键不需要手动输入,而在Hibernate下包含有主键的生成策略。例如第一点的示例中:

    @Id
@Column(name = "ogg_key_id", unique = true, nullable = false)
@GeneratedValue(generator = "systemUUID")
@GenericGenerator(name = "systemUUID", strategy = "uuid")
public String getOggKeyId() {
return oggKeyId;
}
public void setOggKeyId(String oggKeyId) {
this.oggKeyId = oggKeyId;
}

此时,只需要在相应的setter的方法上,设置主键的生成策略(本例中为UUID)Hibernate即可自动生成唯一性标识,而省去了手动输入的麻烦。使用Hibernate映射主键总结几点:

1、为了保证对象标识符的唯一性与不可变性,应该让Hibernate来为主键赋值,而不是程序。

2、Hibernate中唯一一种最简单通用的主键生成器就是:UUID。虽然是个32位难读的长字符串,但是它没有跨数据库的问题,将来切换数据库极其简单方便,推荐使用。

3、Hibernate下的UUID生成和Java下的UUID生成有所不同,Hibernate下是32位字长的16进制数,而Java下的则是36位字长。

4、其他主键的生成策略:assigned、increment、hilo、seqhilo、sequence、identity、native、guid、foreign、select。详解参考:http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html

三、复合主键的表映射 (出现情况不多,不推荐使用复合主键)

复合主键的情况是数据表存在多个主键,在实现与类映射时,情况比单一主键更加复杂。通常情况都会想法设法修改表结构成为单一主键,绕开复合主键,所以不推荐使用。但最近在做项目的时候,遇到表结构是复合主键,也无法绕开的情况,所以按此思路开始。这里我使用的是将主键属性封装在一个类当中,其中要注意的几点:

1. 使用复合主键的实体类必须实现Serializable接口。
必须实现Serializable接口的原因很简单,我们查找数据的时候是根据主键查找的。打开Hibernate的帮助文档我们可以找到get与load方法的声明形式如下:
Object load(Class theClass,Serializable id)
Object get(Class theClass,Serializable id)
当我们查找复合主键类的对象时,需要传递主键值给get()或load()方法的id参数,而id参数只能接收一个实现了Serializable接口的对象。而复合主键类的主键不是一个属性可以表示的,所以只能先new出复合主键类的实例(例如:new People()),然后使用主键属性的set方法将主键值赋值给主键属性,然后将整个对象传递给get()或load()方法的id参数,实现主键值的传递,所以复合主键的实体类必须实现Serializable接口。 . 使用复合主键的实体类必须重写equals和hashCode方法。必须重写equals和hashCode方法也很好理解。这两个方法使用于判断两个对象(两条记录)是否相等的。为什么要判断两个对象是否相等呢?因为数据库中的任意两条记录中的主键值是不能相同的,所以我们在程序中只要确保了两个对象的主键值不同就可以防止主键约束违例的错误出现。也许这里你会奇怪为什么不使用复合主键的实体类不重写这两个方法也没有主键违例的情况出现,这是因为使用单一主键方式,主键值是Hibernate来维护的,它会确保主键不会重复,而复合主键方式,主键值是编程人员自己维护的,所以必须重写equals和hashCode方法用于判断两个对象的主键是否相同。 3. 重写的equals和hashCode方法,只与主键属性有关,普通属性不要影响这两个方法进行判断。这个原因很简单,主键才能决定一条记录,其他属性不能决定一条记录。 4.主键类必须有默认的public无参数的构造方法。

实现复合主键映射的三种方式:

1、@Embeddable + @Id + @Embedded(@Embeddable 表示这个类可以嵌入到别的类中去,常以表示其他类的某个属性。)

2、@Embeddable + @EmbeddedId( @Embedded 它和 @Embeddable 正好相反,它用来表示某个属性是被嵌入进来的。)

3、@IdClass + @Id(@EmbeddedId = @Embedded + @Id)

以下贴出第一种方式的代码:

主键类ModelKey:

package com.pec.model;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class ModelKey implements Serializable{
private static final long serialVersionUID = 8099372586856509841L; // 接口类型
private String intType;
// 条目识别码
private String recordId;
//
private String createTimeStamp;
public String getIntType() {
return intType;
}
public void setIntType(String intType) {
this.intType = intType;
}
public String getRecordId() {
return recordId;
}
public void setRecordId(String recordId) {
this.recordId = recordId;
}
public String getCreateTimeStamp() {
return createTimeStamp;
}
public void setCreateTimeStamp(String createTimeStamp) {
this.createTimeStamp = createTimeStamp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((createTimeStamp == null) ? 0 : createTimeStamp.hashCode());
result = prime * result + ((intType == null) ? 0 : intType.hashCode());
result = prime * result
+ ((recordId == null) ? 0 : recordId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ModelKey other = (ModelKey) obj;
if (createTimeStamp == null) {
if (other.createTimeStamp != null)
return false;
} else if (!createTimeStamp.equals(other.createTimeStamp))
return false;
if (intType == null) {
if (other.intType != null)
return false;
} else if (!intType.equals(other.intType))
return false;
if (recordId == null) {
if (other.recordId != null)
return false;
} else if (!recordId.equals(other.recordId))
return false;
return true;
}
public ModelKey(String intType, String recordId, String createTimeStamp) {
this.intType = intType;
this.recordId = recordId;
this.createTimeStamp = createTimeStamp;
}
public
ModelKey() {
}

}

实现类InterFaceDataModel:

package com.pec.model;

import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import com.sun.tracing.dtrace.Attributes;
@Entity
@Table(name = "interface_admin.interface_data_test")
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)
//@IdClass(ModelKey.class)
public class InterFaceDataModel implements Serializable{
private static final long serialVersionUID = 8586209694356988171L;
private ModelKey modelKey ;
private String seniorRecordId ;
private Timestamp daleteTime ;
private String createUser ;
private String oprStatus ;
private String oprUser ;
private String oprTimeStamp ;
private String yyyymmdd ;
private String selKey1 ;
private String selKey2 ;
private String selKey3 ;
private String selKey4 ;
private String valList ;
@Id
@Embedded
@AttributeOverrides({
@AttributeOverride(name="intType", column = @Column(name="int_type")),
@AttributeOverride(name="recordId", column = @Column(name="record_id")),
@AttributeOverride(name="createTimeStamp", column = @Column(name="create_timestamp"))
})
public ModelKey getModelKey() {
return modelKey;
} public void setModelKey(ModelKey modelKey) {
this.modelKey = modelKey;
}
@Column(name = "senior_record_id")
public String getSeniorRecordId() {
return seniorRecordId;
}
public void setSeniorRecordId(String seniorRecordId) {
this.seniorRecordId = seniorRecordId;
}
@Column(name = "delete_time")
public Timestamp getDaleteTime() {
return daleteTime;
}
public void setDaleteTime(Timestamp daleteTime) {
this.daleteTime = daleteTime;
}
@Column(name = "create_user")
public String getCreateUser() {
return createUser;
}
public void setCreateUser(String createUser) {
this.createUser = createUser;
}
@Column(name = "opr_status")
public String getOprStatus() {
return oprStatus;
}
public void setOprStatus(String oprStatus) {
this.oprStatus = oprStatus;
}
@Column(name = "opr_user")
public String getOprUser() {
return oprUser;
}
public void setOprUser(String oprUser) {
this.oprUser = oprUser;
}
@Column(name = "opr_timestamp")
public String getOprTimeStamp() {
return oprTimeStamp;
}
public void setOprTimeStamp(String oprTimeStamp) {
this.oprTimeStamp = oprTimeStamp;
}
@Column(name = "yyyymmdd")
public String getYyyymmdd() {
return yyyymmdd;
}
public void setYyyymmdd(String yyyymmdd) {
this.yyyymmdd = yyyymmdd;
}
@Column(name = "sel_key1")
public String getSelKey1() {
return selKey1;
}
public void setSelKey1(String selKey1) {
this.selKey1 = selKey1;
}
@Column(name = "sel_key2")
public String getSelKey2() {
return selKey2;
}
public void setSelKey2(String selKey2) {
this.selKey2 = selKey2;
}
@Column(name = "sel_key3")
public String getSelKey3() {
return selKey3;
}
public void setSelKey3(String selKey3) {
this.selKey3 = selKey3;
}
@Column(name = "sel_key4")
public String getSelKey4() {
return selKey4;
}
public void setSelKey4(String selKey4) {
this.selKey4 = selKey4;
}
@Column(name = "val_list")
public String getValList() {
return valList;
}
public void setValList(String valList) {
this.valList = valList;
}
}

具体参考链接:

http://blog.csdn.net/handsomelinux/article/details/50575877

http://www.cnblogs.com/otomedaybreak/archive/2012/01/25/2329390.html

Hibernate 表映射 主键生成策略与复合主键的更多相关文章

  1. 以下哪个Hibernate主键生成策略是实现主键按数值顺序递增的?

    A.increment B.identity C.sequence D.native 解答:A

  2. Hibernate框架笔记02_主键生成策略_一级缓存_事务管理

    目录 0. 结构图 1. 持久化类的编写规则 1.1 持久化和持久化类 1.2 持久化类的编写规则 2. 主键生成策略 2.1 主键的分类 2.2 主键生成策略 3. 持久化类的三种状态[了解] 3. ...

  3. 从实例看hibernate的主键生成策略

    学习了hibernate会发现.hibernate中有实体类.实体类的映射文件.可是我们怎么样才干知道实体类的主键是如何的生成方式呢?hibernate提供的主键生成策略帮我们完美地解答了这个疑问.以 ...

  4. Hibernate学习笔记(三)Hibernate生成表单ID主键生成策略

    一. Xml方式 <id>标签必须配置在<class>标签内第一个位置.由一个字段构成主键,如果是复杂主键<composite-id>标签 被映射的类必须定义对应数 ...

  5. Hibernate(4)——主键生成策略、CRUD 基础API区别的总结 和 注解的使用

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: hibernate的主键生成策略 UUID 配置的补充:hbm2ddl.auto属性用法 注解还是配置文件 h ...

  6. hibernate 注解 主键生成策略

    一.JPA通用策略生成器       通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, 其生成规则由@GeneratedValue ...

  7. 初学Hibernate主键生成策略

    具有业务含义的主键叫自然主键:随机生成,不具备业务含义的字段作为主键,叫代理主键. 在表与POJO类关系映射文件XXX.hbm.xml中,可通过配置id元素下generator节点的class属性指定 ...

  8. hibernate多对多 一对多 及简单入门 主键生成策略

    Hibernate简单使用 入门 通过hibernate的 一对多 多对多轻松看懂hibernate配置 (不使用注解) hibernate对jdbc访问数据库的代码进行轻量级封装,简化重复代码 减少 ...

  9. hibernate框架学习第二天:核心API、工具类、事务、查询、方言、主键生成策略等

    核心API Configuration 描述的是一个封装所有配置信息的对象 1.加载hibernate.properties(非主流,早期) Configuration conf = new Conf ...

随机推荐

  1. spring-boot 和 docker 集成

    描述 java 的 Spring是一个很火的框架,Spring boot 这个也不用说了,Docker 近年也很火热, 本文就介绍下我在 Spring boot + Docker的集成一些经验 :) ...

  2. 《3D Math Primer for Graphics and Game Development》读书笔记2

    <3D Math Primer for Graphics and Game Development>读书笔记2 上一篇得到了"矩阵等价于变换后的基向量"这一结论. 本篇 ...

  3. Module-Zero之启动模板

    返回<Module Zero学习目录> 概览介绍 社交登录 基于Token的认证 单元测试 概览介绍 使用ABP和Module-Zero开始一个新的项目最简单的方式通过ABP官网的模板页面 ...

  4. C# 服务程序 - 调试服务

    前言:本篇文章环境是VS2015,win10.如果有任何的差别,请注意 1. 创建服务程序 1)用VC创建服务程序,叫做 MyTestWindowsService 创建完成之后,可以看到 2)添加安装 ...

  5. Atitit 教育与培训学校 的计划策划 v4 qc18

    Atitit 教育与培训学校 的计划策划 v4 qc18 1.1. 版本历史12. 教育历史的前世今生12.1. 自学vs 家庭学校vs 私立学校vs 公立学校模式 vs 企业内部学校 vs 其他商业 ...

  6. python 日期计算案例

    一.计算两个日期内的所有月 def get_month_interval(start_str, end_str): start_year, start_month = list(map(int, st ...

  7. SpringAOP之动态代理

    一.动态代理: 1.在原有的静态代理的基础上进一步的完善,由于静态代理中,重复写了相同的代码使得代码的整体结构显得冗余,而且还不同的核心类还需要有不用的代理类,是写死了的具体的类.所以需要使用动态代理 ...

  8. sql复习第五次

    1.在数据库范围内,关系的每一个属性值是不可分解的 关系中不允许出现重复元组 由于关系是一个集合,因此不考虑元组的顺序 2.笛卡儿积是两个关系的所有元组组合而成的,而等值联接是由笛卡儿积和选择运算组合 ...

  9. LINQ系列:Linq to Object串联操作符

    串联是一个将两个对象联接在一起的过程.在LINQ中,串联操作将两个集合合并成一个集合,通过Concat操作符实现. Concat 1>. 原型定义 public static IQueryabl ...

  10. java Proxy(代理机制)

    我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...