hibernate之复合主键

对于系统设计而言,应该尽量减少和避免在数据库表中引入与业务逻辑相关的主键关系;将业务逻辑主键引入库表,使得底层数据库表结构与业务逻辑想耦合,如果业务逻辑的变化,将很可能对底层数据库结构产生连带应影响;

例如:在项目开发初期,业务逻辑认为系统中的用户名是不可以重复的,随着新的需求产生,出现了用户名可重复的可能性,这样的话,我们就得从底层数据库开始更改,但是在某些关键的系统中,这样更在某些关键地方,将是一个大工程,这样的工作将难以接受;

这样,复合主键的引入,很大程度上意味着业务逻辑已经侵入到数据存储逻辑之中。因此在新的系统中,应该避免这样的设计;然而在旧的系统中遇到这样的情况,如果有复合主键的支持就显得很必要;

复合主键的使用,以Tuser为蓝本,将那么拆分成两个部分,firstname,lastname,以他们作为复合主键;对于复合主键而言,我们可以通过两种方式确定主键(Hibernate中通过<composite-id>定义复合主键):

 

  • 基于实体类的复合主键

复合主键是由实体类的属性组成,此时,实体类本身也扮演着复合主键类的角色;定义如下(Hibernate要求复合主键类要实现equals和hasCode方法,以作为不同数据之间的标识):

Tuser类:

 

public class Tuser implements Serializable {

	private String firstName;
	private String lastName;

	private List email = new ArrayList();
	private List address = new ArrayList();

        get/set()....

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		result = prime * result
				+ ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result
				+ ((lastName == null) ? 0 : lastName.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;
		Tuser other = (Tuser) obj;
		if (address == null) {
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		return true;
	}
}
 

 

Tuser.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.keith">

	<class name="Tuser" table="tUser">
		<composite-id>
			<key-property name="firstName" />
			<key-property name="lastName" />
		</composite-id>
		<property name="email" type="com.keith.EmailList"></property>
	</class>
</hibernate-mapping>

 

 先添加一条数据(测试代码):

 

                Tuser tUser = new Tuser();
		tUser.setFirstName("keke");
		tUser.setLastName("EEE");
		
		List email = new ArrayList();
		email.add("keith@gmail.com");
		email.add("keith@sina.coom");
		tUser.setEmail(email);
		session.save(tUser);

 

 看下输出的SQL:

 

Hibernate:  insert into   tUser(email, firstName, lastName) values (?, ?, ?)

 

 虽然数据已经添加进去了,但是对于表结构还有点模糊,看下表结构:

 

CREATE TABLE `tuser` (
  `firstName` varchar(255) NOT NULL,
  `lastName` varchar(255) NOT NULL,
  `email` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`firstName`,`lastName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

 这样就一目了然了,测试下如何查询(以tUser作为识别对象,通过session.load()方法加载数据):

 

		Tuser tUser = new Tuser();
		tUser.setFirstName("keke");
		tUser.setLastName("EEE");
		tUser = (Tuser) session.load(Tuser.class, tUser);
		System.out.println("tUser's Email:"+tUser.getEmail());
  •  基于主键类的复合主键

 

我们也可以将主键逻辑加以隔离,以一个单独的主键类对复合主键进行描述;这样我们就需要一个TuserPK类(用来装Tuser的主键):

 

package com.keith;

public class TuserPK implements java.io.Serializable {
	private String firstName;
	private String lastName;

        get()/set()....



	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result
				+ ((lastName == null) ? 0 : lastName.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;
		TuserPK other = (TuserPK) obj;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		return true;
	}
}

 

 在Tuser中就这样:

 

public class Tuser implements Serializable {

	private TuserPK tuserpk;

	private List email = new ArrayList();
	private List address = new ArrayList();

        get()/set()...


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		result = prime * result + ((tuserpk == null) ? 0 : tuserpk.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;
		Tuser other = (Tuser) obj;
		if (address == null) {
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (tuserpk == null) {
			if (other.tuserpk != null)
				return false;
		} else if (!tuserpk.equals(other.tuserpk))
			return false;
		return true;
	}
}

 

 属性文件里要这样(<composite-id name="tuserpk" class="TuserPK">):

 

<?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.keith">

	<class name="Tuser" table="tUser">
		<composite-id name="tuserpk" class="TuserPK">
			<key-property name="firstName" />
			<key-property name="lastName" />
		</composite-id>
		<property name="email" type="com.keith.EmailList"></property>
	</class>
</hibernate-mapping>

添加一条数据:

 

		Tuser tUser = new Tuser();
		TuserPK tUserPk = new TuserPK();
		tUserPk.setFirstName("aaa");
		tUserPk.setLastName("bbb");
		
		tUser.setTuserpk(tUserPk);
		List email = new ArrayList();
		email.add("keith@gmail.com");
		email.add("keith@sina.coom");
		tUser.setEmail(email);
		session.save(tUser);
 

根据主键进行查询:

 

		
		Tuser tUser = new Tuser();
		TuserPK tUserPk = new TuserPK();
		tUserPk.setFirstName("aaa");
		tUserPk.setLastName("bbb");
		tUser = (Tuser) session.load(Tuser.class, tUserPk);
		System.out.println("tUser's Email:"+tUser.getEmail());

 以上就是复合主键的用法!

 

 

深入 Java 领域 Hibernate 的复合主键映射 本文旨在为Java开发者提供关于Hibernate复合主键映射的全面指南。复合主键的基本概念和适用场景Hibernate支持的两种主要映射策略性能考量和最佳实践实际项目中的应用案例首先介绍复合主键的基本概念和为什么需要它然后深入探讨Hibernate中两种实现方式的技术细节接着通过实际代码示例展示具体实现最后讨论性能优化和实际应用场景复合主键(Composite Key): 由多个列组成的主键,用于唯一标识表中的每一行: JPA注解,表示嵌入式复合主键@IdClass。 阅读详情

相关推荐

Hibernate复合主键映射详解及实践

Hibernate框架作为Java领域持久层解决方案的佼佼者,提供了强大的对象关系映射(ORM)能力,其中复合主键映射是其核心功能之一。本章旨在为读者介绍Hibernate复合主键映射的基本概念,以及在实现数据库持久化操作时,如何有效地利用复合主键来确保数据的唯一性和准确性。复合主键类需要使用注解来定义。这是告诉Hibernate这个类可以被嵌入到一个实体类中作为复合主键使用。在定义复合主键类时,需要考虑以下要素:使用注解:标记类为可嵌入的复合主键类。私有属性。

weixin_42605397的博客 1130

Hibernate主键之复合主键

在hibernate中复合主键的有两种实现方式(simple demo) Composite-id class must implement Serializable 现分别用这两种实现方式举个栗子: 数据库中的选课表 score(s_id,c_id,s_score);其中PK(s_id,c_id) 学生编号与课程编号为复合主键 (1)基于持久化类属性的复合主键 Ja...

一只胖胖胖miao 466

Hibernate复合主键

一个简单的复合主键的做关联类的例子

Hibernate联合主键

在实际开发中,数据库表之间关系有很多种情况,其中共有一个是联合主键,就是中由两个以上的属性同时担任主键, 今天我们就来学习一下,联合主键怎么设计实体类,以及怎么写实体类对应的配置文件*.hbm.xml, 新建一个项目名称为:06hibernate_composite_id,结构如下: 项目以分数实体类为例, 导入jar包,参见《Hibernate环境搭建和配置》

红桃峰峰 的博客 1306

S32DS使用完整指南:S32K CAN通信模块配置步骤

深入讲解S32DS使用过程中S32K芯片的CAN通信模块配置步骤,涵盖关键设置与常见问题。掌握s32ds使用技巧,提升开发效率,实现稳定可靠的车载网络通信。

weixin_42592399的博客 981

优化Cartographer重定位速度:从子图筛选到参数调优的完整思路

本文详细介绍了优化Cartographer重定位速度的完整方法,从子图筛选到参数调优,帮助工程师在已知初始位姿的前提下将重定位耗时降低50%以上。重点分析了性能瓶颈、子图筛选策略、匹配算法选择及环境自适应的参数优化策略,并通过实战案例展示了显著效果提升。

weixin_28704565的博客 464

hibernate saveOrupdate操作含有联合主键的对象问题

环境:jdk1.6   框架:SSH 服务器:resin 首先交代下大概业务,实体A(某一行业属性配置)、实体B(行业功能,such as 发送短信的机制)、其中A种使用联合主键; 行业初始化时,保存当前行业的机制(保存B对象),同时保存该机制的属性配置(保存A对象); 以上过程通过saveOrupdate操作完全没有问题; 但在相同行业下新增一个机制B ; A也随之增加,走之

以梦为马 4311

gem5 prefetcher

最近在gem5上做预取实验,添加自己的预取算法,这里采用hardware stream prefetcher , 修改了几个bug才给实验调试通过,发文记录下实验过程。 gem5上添加自己的预取算法步骤: (1)路径gem5-master/configs/common/Caches.py下,开启预取:class L1Cache(Cache): assoc = 2 tag_late

编程邦 3844

Hibernate复合主键的注解

最近做项目用到了Hibernate框架,采用了纯面向对象的思想,使用ORM映射实体。在开发中,实体中出现了复合主键,不再是单一的属性作主键,由于采用了注解的方式,就不再使用xml文件进行配置了,而是直接在实体中进行注释。 Hibernate注解规范的文档中提供了三种方法:      1. 将组件类注解为@Embeddable,并将组件的属性注解为@Id;      2. 将组件的属性

紫羽风的博客 2万+

破解雪球网acw_sc__v2加密与无限debugger反爬策略

本文详细解析了雪球网的反爬机制,重点破解了其核心的acw_sc__v2加密参数与无限debugger反调试策略。通过实战案例,从抓包分析、逆向调试到算法还原,提供了完整的Python代码实现,帮助开发者掌握应对类似加密反爬的通用方法。

weixin_29207533的博客 1897

hibernate中复合主键

复合主键:一张表的多个字段组合构成这张表的主键,这个主键就叫复合主键。 在hibernate中配置复合主键: Hibernate复合主键的编写有两种情况: 1、将复合主键各字段定义为私有属性。 2、将复合主键字段抽取出来定义一个主键类(暂且这样称呼),在实体类中包含主键类即可。(推荐使用这种方法) 映射文件的编写: 复合主键使用: 方式一: 由几个字段构成添加几个

Imust_can的专栏 2366

永磁同步电机功率计算实战:从公式到避坑指南(附Excel计算模板)

本文详细解析永磁同步电机(PMSM)功率计算的实战技巧,涵盖三维参数体系、三相与单相系统差异、动态工况补偿及常见计算陷阱。特别提供Excel计算模板,帮助工程师快速准确完成功率计算,避免工业应用中的常见错误,提升工作效率。

x8y9z0的博客 806

hibernate 复合主键 注解

Hibernate注解规范的文档中提供了三种方法: 1. 将组件类注解为@Embeddable,并将组件的属性注解为@Id; 2. 将组件的属性注解为@Embeddable; package com.cmh.beans;import javax.persistence.Embeddable; import java.io.Serializable;@Embeddable publ

ooiuy450的专栏 5754

基于SpringBoot 3 + Vue 3的全栈民宿预约管理系统设计与实现

文章将详细阐述系统的需求分析、架构设计、数据库设计、核心功能模块的实现(包括用户认证、房源管理、订单流程、支付集成等),并提供关键代码片段,最后对系统进行总结与展望。.requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口。.requestMatchers("/api/auth/**").permitAll() // 认证接口公开。.requestMatchers("/api/public/**").permitAll() // 公开资源。

2201_76125393的博客 272

基于机器学习的网络入侵检测系统设计与实现

本文设计并实现了一个基于机器学习的网络入侵检测系统,采用随机森林模型结合KMM算法优化,使用CICIDS2017数据集进行训练。系统包含完整的数据预处理流程、特征工程、模型调优和远程部署方案。实验结果表明,该系统能有效识别多种网络攻击类型,在检测准确率和误报率方面表现优异。研究为网络安全防护提供了新的技术思路和实用工具,具有重要的应用价值。

huanghm88的专栏 318

Hibernate实现复合主键的使用

复合主键的使用 1>:首先将要作为主键的属性首先抽取成单独的实体 并提供get And set方法 并且还需要序列化 2>:在实际的实体中申明主键实体的变量 3>:在映射文件中编写实体的配置文件

GuominJin的博客 4730

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Hibernate中复合主键的配置和使用

有关Hibernate的联合主键 对于新系统的设计开发而言,我们应尽量避免在库表中引入与业务逻辑相关的主键关系。 将业务逻辑主键引入库表,以后业务逻辑的变化,将很可能对底层数据库结构产生连带影响。 复合主键的引入,很大程度上意味着业务逻辑已经侵入到数据存储逻辑之中。 因此,应尽量避免。但实际情况中,我们必须面对遗留系统的旧表开发,这时,对现有复合主键的支持就非常必要。 hiberna

haikuotiankong1997的专栏 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Hibernate复合主键映射

目录: 1. 实现方式一:将复合主键对应的属性与实体其他普通属性放在一起 2. 实现方式二:将主键属性提取到一个主键类中,实体类只需包含主键类的一个引用   在日常开发中会遇到这样一种情况,数据库中的某张表需要多个字段列才能唯一确定一行记录,这时表需要使用复合主键。面对这样的情况Hibernate为我们提供了两种方式来解决复合主键问题。 方式一:将复合主键对应的属性与实体其他普...

lgxzzz的博客 189

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

关于Hibernate的复合主键查询

Hibernate查询是以主键的方式查询的,如查询的主键有重复,有多条记录复合查询条件的话,会导致查询出的记录不完整,Hibernate只能取出一条记录。所以就需要在在设计Hibernate的映射文件的时,就需要做成复合主键(该复合主键可以不和DB的主键相关联)。

风火的专栏 2750

【Hibernate步步为营】--复合主键映射详解

复合主键的使用其实很简单,但是需要注意对象需要被拆分,主键自己需要一个类并且该类需要实现java.io.Serializable接口,其它的属性再重新生成新类,并且类的属性中要有主键类的对象,相应的只需要一个配置文件,在映射文件中使用<composite-id>指明主键,并指明主键的属性。

航帆远洋 5182

10 15 Hibernate之复合主键映射

文章目录1 基于HBM文件的配置2 Annotation配置 首先在开发之中复合主键是一中强烈不建议使用的技术,在任何一张数据表里面如果要设置主键应该只设置一个字段,但是复合主键毕竟属于标准的SQL语法,所以在Hibernate或者是JPA之中也都有复合主键的定义支持。 范例:数据库脚本 -- 删除数据表 DROP TABLE IF EXISTS member; -- 创建数据表 CREATE TABLE member( mid VARCHAR(50), mname VARCHAR(50), mage

weixin_43762330的博客 382
上一篇: UserType用法1
下一篇: hibernate之Blob,Clob字段
keithJava
博客等级 码龄16年 2粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值