Hibernate之实体层次设计

继承是关系型数据与面向对象数据结构之间的主要差异之一,如何在关系型的数据之上可以像面向对象数据那样清晰的表达之间的逻辑关系;Hiberante中支持3种类型的继承形式:

 

  • table per concrete class(表与子表之间的独立一对一关系)

在面向对象的设计中会有继承关系,在hibernate可以这么来实现:比如,一个电子商务网站会出售DVD和Book,它们的共性就是会有名字和厂商,而不同之处在于DVD会有区域码,而book会有作者;那么在面向对象的设计中,我们会想将共性构造一个基类,然后在对基类进行扩展如:

父类TItem:

 

public class TItem implements java.io.Serializable{
	private Integer id;
	private String name;
	private String company;
        get()/set()
}

子类TBook:

 

public class TBook extends TItem {
	private String author;
        get()/set()
}

 

 子类TDvd:

 

public class TDvd extends TItem {
	private String regionCode;
        get()/set()
}

 

 在*.hbm.xml中直接这么定义:

TBook.hbm.xml:

 

<hibernate-mapping package="com.keith.tablePerConcreteClass">
	<class name="TBook" table="TBook">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name" />
		<property name="company" />
		<property name="author" />
	</class>
</hibernate-mapping>

 

 TDvd.hbm.xml:

 

<hibernate-mapping package="com.keith.tablePerConcreteClass">
	<class name="TDvd" table="TDvd">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name" />
		<property name="company" />
		<property name="regionCode" />
	</class>
</hibernate-mapping>

 

 测试下:添加数据:

 

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		TBook book = new TBook();
		book.setName("java Code");
		book.setAuthor("king");
		book.setCompany("EN");
		
		TDvd dvd = new TDvd();
		dvd.setName("2012");
		dvd.setRegionCode("0404040404");
		dvd.setCompany("ZH");
		
		session.save(book);
		session.save(dvd);
		session.getTransaction().commit();

 

 日志中这样输出:

 

    create table TBook (
        id integer not null auto_increment,
        name varchar(255),
        company varchar(255),
        author varchar(255),
        primary key (id)
    )
 

 

 

    create table TDvd (
        id integer not null auto_increment,
        name varchar(255),
        company varchar(255),
        regionCode varchar(255),
        primary key (id)
    )

 

 

 Hibernate: insert into  TBook(name, company, author) values (?, ?, ?)
Hibernate:insert  into  TDvd (name, company, regionCode) values (?, ?, ?)

 党我们查询时:

 

	        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List list =session.createQuery("from com.keith.tablePerConcreteClass.TItem").list();
		Iterator it = list.iterator();
		while (it.hasNext()) {
			TItem item = (TItem) it.next();
			System.out.println(item.getName());
		}
		session.getTransaction().commit();	

 

 看下输出的日志:

 

Hibernate: 
    select
        tbook0_.id as id0_,
        tbook0_.name as name0_,
        tbook0_.company as company0_,
        tbook0_.author as author0_ 
    from
        TBook tbook0_
Hibernate: 
    select
        tdvd0_.id as id1_,
        tdvd0_.name as name1_,
        tdvd0_.company as company1_,
        tdvd0_.regionCode as regionCode1_ 
    from
        TDvd tdvd0_

 

 查询了2个表的内容,结果是:

 

java Code
2012

 通过这样的方式我们将继承关系在持久层得到体现,可是如果我们要根据name类查询某件商品,这是会将所有的表全部查询一遍,然后进行汇总,如果这样的,性能大大的降低!

 

  • table per subclass(每个子表对应一张子表,并与主类共享主表)

如果父类表发生变化,那么其子类就得跟着变化,这样太不灵活,我们可以将父类表(TItem)单独映射到一个主表中,而为TBook,TDvd分别单独设立一张子表,子表中包含所扩展的属性,同时子表和父表可以通过关系型数据库的外键想关联;

对象没有变化,还是上面那么种写法,既然父类是一个主表了,子类是扩展属性的那么我们就根据外键来执行相应的操作;

这里只需要一个TItem.hbm.xml:

 

<hibernate-mapping package="com.keith.tablePerSubclass">
	<class name="TItem" table="TItem">
		<id name="id" type="java.lang.Integer" column="TItem_id">
			<generator class="native"/>
		</id>
		<property name="name" />
		<property name="company" />
		
		<joined-subclass name="TBook" table="tBook">
			<key column="TItem_id"></key>
			<property name="author" />
		</joined-subclass>
		
		<joined-subclass name="TDvd" table="tDvd">
			<key column="TItem_id"></key>
			<property name="regionCode" />
		</joined-subclass>
	</class>
</hibernate-mapping>

 

 添加数据也后我们看下日志信息:首先会创建一个主表:

 

    create table TItem (
        TItem_id integer not null auto_increment,
        name varchar(255),
        company varchar(255),
        primary key (TItem_id)
    )

 

 tBook:

 

    create table tBook (
        TItem_id integer not null,
        author varchar(255),
        primary key (TItem_id)
    )

 

 tDvd:

 

    create table tDvd (
        TItem_id integer not null,
        regionCode varchar(255),
        primary key (TItem_id)
    )

 

 并对其子类进行关联:

 

23:00:33,791 DEBUG SchemaExport:377 - 
    alter table tBook 
        add index FK682557D53D2350B (TItem_id), 
        add constraint FK682557D53D2350B 
        foreign key (TItem_id) 
        references TItem (TItem_id)
23:00:33,842 DEBUG SchemaExport:377 - 
    alter table tDvd 
        add index FK35C8FE53D2350B (TItem_id), 
        add constraint FK35C8FE53D2350B 
        foreign key (TItem_id) 
        references TItem (TItem_id)

 

 添加时候也会按照下面的顺序来执行:

 

Hibernate: insert  into TItem(name, company) values(?, ?)
Hibernate:insert  into   tBook(author, TItem_id) values  (?, ?)

Hibernate: insert into TItem(name, company) values(?, ?)
Hibernate: insert into  tDvd(regionCode, TItem_id) values(?, ?)

 

 当我们查询的时候:

 

Hibernate: 
    select
        titem0_.TItem_id as TItem1_0_,
        titem0_.name as name0_,
        titem0_.company as company0_,
        titem0_1_.author as author1_,
        titem0_2_.regionCode as regionCode2_,
        case 
            when titem0_1_.TItem_id is not null then 1 
            when titem0_2_.TItem_id is not null then 2 
            when titem0_.TItem_id is not null then 0 
        end as clazz_ 
    from
        TItem titem0_ 
    left outer join
        tBook titem0_1_ 
            on titem0_.TItem_id=titem0_1_.TItem_id 
    left outer join
        tDvd titem0_2_ 
            on titem0_.TItem_id=titem0_2_.TItem_id

 会比上一种方法减少能源消耗!但是对于性能有很高的要求系统而言,以上2中方式都不可选,多表操作的性能消耗是十分可观的!

 

  • table per class hierarchy(表与类的一对多关系)

综合以上的考虑,我们可以这样设计,将两种实体映射到一个对象里,比如可以用category来区分;1就是dvd,2就是book;其中实体类应该这样写:

TItem:

 

public class TItem implements java.io.Serializable {
	private Integer id;
	private Integer category;
	private String name;
	private String company;
	private String regionCode;
	private String author;

	public TItem() {
	}
        get()/set()
}

 

 其映射文件可以这样TItem.hbm.xml:

 

<hibernate-mapping package="com.keith.tablePerClassHierarchy">
	<class name="TItem" table="TItem">
		<id name="id" type="java.lang.Integer" column="TItem_id">
			<generator class="native"/>
		</id>
		<discriminator column="category" type="string"></discriminator>
		<property name="name" />
		<property name="company" />
		
		<subclass name="TDvd" discriminator-value="1">
			<property name="regionCode" />
		</subclass>
		
		<subclass name="TBook" discriminator-value="2">
			<property name="author" />
		</subclass>
	</class>
</hibernate-mapping>

 

当我们添加一个对象时:

先看下建表SQL:

 

    create table TItem (
        TItem_id integer not null auto_increment,
        category varchar(255) not null,
        name varchar(255),
        company varchar(255),
        regionCode varchar(255),
        author varchar(255),
        primary key (TItem_id)
    )

 

 添加数据的SQL:

 

Hibernate: 
    insert 
    into
        TItem
        (name, company, category) 
    values
        (?, ?, 'com.keith.tablePerClassHierarchy.TItem')

Hibernate: 
    insert 
    into
        TItem
        (name, company, category) 
    values
        (?, ?, 'com.keith.tablePerClassHierarchy.TItem')

 

 当我们查询的时候:

 

Hibernate: 
    select
        tbook0_.TItem_id as TItem1_0_,
        tbook0_.name as name0_,
        tbook0_.company as company0_,
        tbook0_.author as author0_ 
    from
        TItem tbook0_ 
    where
        tbook0_.category='2'

Hibernate: 
    select
        tdvd0_.TItem_id as TItem1_0_,
        tdvd0_.name as name0_,
        tdvd0_.company as company0_,
        tdvd0_.regionCode as regionCode0_ 
    from
        TItem tdvd0_ 
    where
        tdvd0_.category='1'

 自己就默认找到了!

附上源文件,及测试代码!

Java 领域 Hibernate 实体类设计要点 本文旨在为 Java 开发者提供 Hibernate 实体类设计的全面指南,涵盖从基础到高级的各种设计技巧和最佳实践。实体类的基本结构和注解使用各种关联关系的设计与实现继承策略的选择与比较性能优化技巧常见陷阱与规避方法本文的范围限定在 Hibernate 作为 ORM 框架的实体类设计层面,不涉及 Hibernate 的其他功能如查询、缓存等。首先介绍背景和基本概念然后深入探讨核心设计原则和技术细节接着通过实际案例展示各种设计模式最后讨论性能优化和未来趋势。 阅读详情

相关推荐

实战解析:利用Wireshark解密QQ通信协议

本文提供了一份利用Wireshark工具分析QQ通信协议的实战指南。文章详细介绍了从环境准备、捕获数据包到解析协议层的完整流程,重点演示了如何识别QQ号码字段、观察加密数据特征以及区分不同通信类型(如文本、文件传输)。通过此实践,读者可以深入理解网络分层模型和现代应用加密通信机制,提升网络协议分析与安全诊断能力。

weixin_29210727的博客 408

hibernate笔记一

刚写了一个hibernate的一个超级简单的数据库操作实例,为了以后的方便,就把它记录下来了 1、引入相应的jar包,包括hibernate以及它下面的lib文件夹中的所有jar包,把他们打包成一个library,然后加载到eclipse中, 2、引入hiberbate的相关配置文件到项目的src目录下, 3、配置hibernate.cfg.xml 主要是配置数据库的连接。

zsf0615020117的专栏 399

从零到一:手把手教你用海康VisionMaster完成第一个字符识别项目(附完整流程与避坑点)

本文详细介绍了如何使用海康VisionMaster完成首个字符识别项目,涵盖从环境搭建、图像预处理到系统集成的完整流程。特别分享了Blob分析配置、字符识别优化等实战技巧,帮助开发者避开常见陷阱,快速掌握VisionMaster的基本操作,提升工业自动化场景下的字符识别效率。

weixin_29313423的博客 667

五、SpringCloud之商品服务

一、Eureka Server pom.xml 引入相关依赖 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:...

白夜行悟空 645

H5获取手机相机或相册图片两种方式-Android通过webview传递多张照片给H5

H5调用公共获取图片文件方法,在android手机端,H5主要依赖Webview,这边在webview声明并重写该方法onShowFileChooser使用工具类打开相机或相册,可以两种方式安卓原生方式或者利用第三方组件库方式选中图片,返回uri列表给H5H5收到uri照片列表,并且使用前端方式展示创造价值,乐哉分享!

m0_74823947的博客 3096

手把手教你用Cesium和RayMarching实现逼真体积云(附完整Shader代码)

本文详细介绍了如何利用Cesium和RayMarching技术实现逼真的体积云效果,包括环境准备、核心逻辑、云层建模和光照增强等关键步骤,并提供了完整的Shader代码。通过噪声函数选型、动态风场模拟和多重散射近似等技术,开发者可以在数字地球可视化项目中创建沉浸式天气效果,显著提升场景的真实感。

weixin_29230649的博客 415

Hibernate实体层次设计(三)

Table per subclass:父类TItem单独映射到一张主表,为子类TBook、TDVD分别单独设立一张子表,子表中只包含子类所扩展的属性。同时,子表通过关系型数据库的外键相关联,如下图所示:数据关系图如下:1.表定义sql如下use sample;DROP TABLE T_DVD;DROP TABLE T_Book;DROP TABLE

在水一方 616

HTB_Bike靶机之模板注入

船到桥头自然直 文章目录信息收集模板引擎SSIT 模板注入后放答案 信息收集 日常 A 扫描,两个端口 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA) | 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:.

网络安全学习 798

Hibernate实体层次设计(一)

Hibernate中支持3种类型的继承形式:1.Table per concrete class表与子类之间的独立一对一关系。2.Table per subclass每个子类对应一张子表,并与主类共享主表。3.Table per class hierarchy表与类的一对多关系3种方法的比较。 比较方面

在水一方 655

使用Qt和MX Component插件实现与菱PLC的通信

在本文中,我们介绍了如何使用Qt和MX Component插件实现与菱PLC的通信。我们首先安装和配置了MX Component插件,并在Qt项目中初始化和使用MX Component来连接、读取和写入PLC的数据。安装完成后,您需要在Qt项目中配置MX Component的路径,以便Qt可以找到所需的库文件。在本文中,我们将探讨如何使用Qt和MX Component插件来实现与菱PLC的通信。在主函数中,我们将初始化MX Component,并创建一个与PLC通信的示例。在上面的代码中,我们使用了。

TlScratch的博客 996

华为OD机试 - 机器人活动区域(Java 双机位C卷 200分)

现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。之后M行表示网格数值,每行N个数值(数值大小用k表示),数值间用单个空格分隔,行首行尾无多余空格。说明:图中绿色区域,相邻网格差值绝对值都小于等于1,且为最大区域,对应网格点数目为6。M、N、k均为整数,且1

学Java,找哪吒 916

Hibernate实体层次设计(四)

Table per class hierarchy前两种方式,都要进行多表操作,这样带来的性能的消耗量是相当可观的,不利于高并发量的数据存取。Table per class hierarchy提供了另外一中选择。实际开发中,通过冗余字段表达同类型数据是很多情况下的选择。建立一个数据表T_Item包含了所有商品可能用到的字段。另外,为了区分不同的商品,还需要引入一个用于区分的字段

在水一方 672

把 ABAP ALE Change Pointers 讲透:从 CDHDR/CDPOS 到 BDCP2,再到 RBDMIDOC 的自动分发链路

摘要:SAP ALE Change Pointers机制在系统集成中实现业务变更与数据分发的解耦。它记录业务对象变更(如SAP主数据修改),但不立即发送,而是由后续分发逻辑决定发送时机和方式。该机制包含两层:Change Documents记录审计级变更明细,Change Pointers标记需分发的关键变更。配置核心包括全局开关、消息类型激活和字段选择。典型应用如零售价格条件变更自动推送至POS系统,通过BDCP2表存储待处理队列,由RBDMIDOC程序定时评估生成IDoc。运维需关注定期清理和性能优化,

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 209

Hibernate实体层次设计(二)

Table per concrete class方式:TItem有两个子类:TBook、TDVD。按照Table per concrete class方式,每个字类对应一张数据库表。对应于TBook和TDVD,我们有以下库表:1.数据库库表T_Book.sqlDROP TABLE T_Book;CREATE TABLE T_Book (       

在水一方 604

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

hibernate实体层次设计之三种类型的继承形式(三)

l1976135784 1279

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

hibernate实体层次设计之三种类型的继承形式(一)

l1976135784 1287

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

hibernate实体层次设计之三种类型的继承形式(二)

l1976135784 1330

《深入浅出Hibernate》(2)实体层次分析,数据关联等

1。实体层次设计:分为3类A。Table per concret class表与子类之间独立的一对一关系,父类不独立设表。因此子类表的父类字段必须保持一致,如果父类发生变动,相应子类也要发现更改。在某些应用中,如果要对父类进行查询,必须对所有子表进行查询并汇总,性能低下。那么,我们是否可以把父类独立成表?B。Table per subclass父类独立成表,子表中只保存所扩展属性,

花非花 1908

java hibernate构架,浅析Java的Hibernate框架中的继承关系设计

这次我们来说一下hibernate的层次设计,层次设计也就是实体之间的继承关系的设计。也许这样比较抽象,我们直接看例子。1)我们先看一下普通的做法直接上代码:三个实类如下:?这里我们需要三个映射文件,内容如下:?很普通的映射文件,跟以前的没什么区别。下面我们直接写一个测试方法:?注意,这里我们是用TItem类,而不是具体的字类,这里它会自动去查找继承于TItem类的子类,查出所有结果。这里涉及到一...

weixin_33256096的博客 141

Hibernate笔记之4实体层设计

Hibernate继承关系有如下3映射类型对应:1.table per concrete class   也就是表与子类之间独立的一对一关系。即每个子类对应一张表。2.table per subclass  每个子类对应一张子表,并与主类共享主表3. table per class hierarchy  表与类的一对多关系第二种映射策略举例:先看数据库文件:-- 删除表DROP TABLE T

wzwjr的专栏 931

系统架构设计师教程(十三)层次式架构设计理论与实践

层次式架构是软件体系结构设计中最为常用的一种架构形式,它为软件系统提供了一种在 结构、行为和属性方面的高级抽象,其核心思想是将系统组成为一种层次结构,每一层为上层 服务,并作为下层客户。本章重点介绍了层次式架构中的表现层、中间层、访问层和数据层的 体系结构设计技术,给出了层次式架构的案例分析。

赫凯的博客 2139

Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)

在前两章我为大家详细分析了JAR包的选择和必须的配置文件,那么这一章,我就对例子的层次结构进行说明,并实现除WEB层的功能代码。     第三部分:建立框架代码     工程结构          大家可以看到,本例一共分为:dao、entity、service、web四层。另外在这些层次下,还以业务功能再进行分包,这样做是为了方便在以后的功能扩展中,能更好的管理和维护代码。如果将所有类都

TalkingCoding 737

eclipse从数据库逆向生成Hibernate实体类

做项目必然要先进行数据库表设计,然后根据数据库设计建立实体类(VO),这是理所当然的,但是到公司里做项目后,让我认识到,没有说既进行完数据库设计后还要再“自己”建立一变VO。意思是,在项目设计时,要么根据需求分析建立实体类,由正向生成数据库表;要么就先进行数据库表设计,再逆向生成实体类。没有说进行完任意一方的设计后再去花时间去自己匹配建立另一方的设计。 原因是: 1. 1.5倍工作量,浪费时间

鹏霄万里展雄飞 16万+
上一篇: jsp:userBean:The value for the useBean class attribute is invalid 问题
下一篇: 联表查询_V1
keithJava
博客等级 码龄16年 2粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值