ORM——数据库表与Java对象映射原理
来源:互联网 发布:腾讯软件管理官方下载 编辑:程序博客网 时间:2024/05/08 13:40
github实例参考:hibernate各种映射实例——XML、annotation
定义:
- ORM(Object Relation Mapping):利用描述对象和数据库之间映射的元数据,自动且透明地把Java应用程序中的对象持久化到关系数据库中的表。
对象、关系范式的不匹配
关联表示的区别:面向对象语言利用对象引用(object reference一对一、一对多、多对一、多对多);关系领域中使用外键(foreign key 一对多或一对一)表示。
访问数据的区别:面向对象语言利用引用,从一个对象过渡到另一个对象,如同对象遍历一样访问数据;关系领域通过表的联结来访问数据。
映射粒度:细粒度意味着类比表多
继承、多态在数据库中无法直接表示
映射概念和策略
领域模型与元数据
实现领域模型POJO类
ORM元数据(XML、注解):类、表、属性、列、关联、外键、Java类型与SQL类型映射等
// 常用注解- @GeneratedValue(strategy=GenerationType,generator="") - 可选,用于定义主键生成策略。Strategy - 表示主键生成策略,取值有: - GenerationType.AUTO - 根据底层数据库自动选择(默认),若数据库支持自动增长类型,则为自动增长。 - GenerationType.IDENTITY - 根据数据库的Identity字段生成,支持DB2、MySQL、MS、SQL Server、SyBase与HyperanoicSQL数据库的Identity类型主键。 - GenerationType.SEQUENCE - 使用Sequence来决定主键的取值,适合Oracle、DB2等支持Sequence的数据库,一般结合@SequenceGenerator使用。(Oracle没有自动增长类型,只能用Sequence) - GenerationType.TABLE - 使用指定表来决定主键取值,结合@TableGenerator使用。- @Column(name=attribute,nullable=true,unique=false,length=256,insertable=true,updateable=true,columnDefinition="Date=>DATE,TIME,TIMESTAMP or String=>VARCHAR,BLOB,TEXT")
映射持久化类
定义(重要):
- 实体类型的对象:对应数据库中的一张表(具有主键值);对实体对象的引用被持久化为数据库中的引用(一个外键);实体对象具有自己的生命周期。
值类型的对象:没有对应的表,做为实体对象的组件(属性);不支持引用,对于相同的值对象,每个实体对象都有自己的值对象实例;并且它的持久化被嵌入到自身实体的表行中。常见的值类型为Java的基本类型,另外再加上自定义的值类型类。
例子:实体类型(User、BillingDetails)、值类型(Address)类映射选项
- 基础的属性和值类型组件映射
<component>
继承和定制类型
InheritanceType:Hibernate提供3种方式
@ 每个类一张表——TABLE PER CLASS
@ 每个子类一张表——JOINED
@ 每个类层次结构一张表——SINGLE TABLE
每个带隐式多态的具体类一张表:
- 1、不支持多态关联,因为关联在数据库中被表示为外键约束,对于User与BillingDetails的One2Manny关系无法通过一个外键引用两张表。
- 2、不同表的不同列具有完全相同的语义,使得数据库范式变得复杂,对于基类属性的改变会影响到子类属性。
- 3、适用于类层次结构的最顶层,最顶层通常不需要多态。
<generator class="native" />
每个带有联合的具体类一张表——每个类一张表(TABLE_PER_CLASS)
- 共享父类的属性
@Entity@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) //父类配置public abstract class BillingDetails {}@Entity@Table(name="CREDIT_CARD")public class CreditCard extends BillingDetails {}
- 每个类层次结构一张表(SINGLE_TABLE)
- 1、它是表示多态的最佳方式——多态和非多态的查询都执行得横好,并且更易于手工实现。schema也很简单。
- 2、子类生成的属性列必须声明为空。
- 3、创建了非键列之间的功能依赖,违背了第三范式。
@Entity@Inheritance(strategy=InheritanceType.SINGLE_TABLE) //父类配置@DiscriminatorColumn( name="discriminator", discriminatorType=DiscriminatorType.STRING)public abstract class BillingDetails {}@Entity@DiscriminatorValue("CC")public class CreditCard extends BillingDetails {}
- 每个子类一张表:把继承关系表示为相关的外键关联(JOINED)
- 1、表继承关系表示为相关的外键,声明持久性属性的每个类、子类(抽象、接口)都有自己的表。
- 1、表继承关系表示为相关的外键,声明持久性属性的每个类、子类(抽象、接口)都有自己的表。
@Entity@Inheritance(strategy=InheritanceType.JOINED)public abstract class BillingDetails {}@Entity@PrimaryKeyJoinColumn(name="CREDIT_CARD_ID")public class extends BillingDetails {}//
- 混合继承策略:把一个类层次结构映射到单张表,但是对于特定的子类,则通过外键映射策略切换到单独的表,就像使用每一个子类一张表一样。
映射集合和实体关联
值类型的set、bag、list、map和组件集合映射(值类型的类——
<composite-element>``<component>
)ManyToOne——双向关联
public class Bid { @ManyToOne @JoinColum(name="ITEM_ID", nullable=false) private Item item;}public class Item { @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE}, mappedby="item") private Set<Bid> bids= new HashSet<Bid>();}// 1、双向关联——mappedby:把Bid的item端做的变化传播到数据库中。/* 1.1、在运行时,同一个外键值有两个不同的内存表示,Bid的item属性和由Item保存的bids集合的一个元素。当应用程序修改关联时:Hibernate会检查到内存持久化实例的两次变化,这两者更新同一个外键列,从数据库的角度来看,只有一个值需要更新——BID的ITEM_ID列。*/bid.setItem(item);item.getBids().add(bid);// 1.2、通过`mappedby="item"`属性,显示告诉Hibernate把`Bid`端的item所做的变化传播到数据库中。bid.setItem(item);item.getBids().add(bid);// 2、级联操作——CascadeType:当Item持久化时,同时持久化Bid。// 2.1、没有CascadeTypeItem newItem = new Item();Bid newBid = new Bid();newItem.addBid(newBid);session.save(newItem);session.save(newBid);// 2.2、使用CascadeTypeItem newItem = new Item();Bid newBid = new Bid();newItem.addBid(newBid);session.save(newItem);
- javax.persistence.CascadeType.cascade:设置级联方式
- CascadeType.PERSIST(级联新建)
- CascadeType.REMOVE(级联删除)
- CascadeType.REFRESH(级联刷新)
- CascadeType.MERGE(级联更新)
- CascadeType.ALL(全部四项)
fetch - 配置加载方式。取值有
- Fetch.EAGER - 及时加载,多对一默认是Fetch.EAGER
- Fetch.LAZY - 延迟加载,一对多默认是Fetch.LAZY
OneToOne
ManyToMany:多对多关联始终可以表示为对中间类的两个多对一关联。
会话对象管理
持久化管理器:Session、Query、Criteria、Transaction
扩展持久化上下文:每个请求一个会话而不是每个操作一个会话。实现DAO的共享持久化上下文。
- 通过Hibernate ThreadLocal Session传播
- 通过JTA传播
利用Hibernate的对话
- 利用托管对象的对话。
- 给会话扩展Session,也就是上面两种会话传播。
HQL类似于SQL:这两者的区别在于HQL使用类名称而不是表名称,使用属性名称而不是列名称。它可以理解继承——可使用超类、接口查询。
对象获取
- 导航对象图
- 通过标识符获取
- HQL
- sql
- ORM——数据库表与Java对象映射原理
- ORM中对象与数据库表之间的映射机制
- Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包
- Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java
- 简单的数据库表到对象的ORM映射
- 浅谈ORM对象关系数据库映射
- 持久层与对象数据映射(ORM)
- IOS对象关系映射(ORM)之coreData框架的学习——(二)原理剖析及使用步骤详解
- hibernate ORM映射——单表映射
- ORM 对象关系映射
- ORM 对象关系映射
- ORM对象关系映射
- 对象关系映射ORM?
- ORM-对象关系映射
- ORM对象/关系映射
- ORM:对象关系映射
- ORM建立类->数据库表的映射
- android中ORM(对象关系映射)数据库LitePal的使用
- SDUT3374数据结构实验之查找二:平衡二叉树
- spark 监控--WebUi、Metrics System
- 剑指offer----链表中环的入口节点----java实现
- netbeans 控制台乱码
- 数字化转型,企业需要何种网络架构?
- ORM——数据库表与Java对象映射原理
- Android 主题动态切换框架:Prism
- Spark 资源调度及任务调度
- Android View框架总结(二)View工作原理
- PXE网络启动 windows PE (使用微软官方工具)
- java 内存泄露
- iOS开发技巧:布局UIButton的imageView和titleLabel属性
- Nagios安装_客户端
- [leetcode] 137. Single Number II