定义:
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)

类映射选项
基础的属性和值类型组件映射继承和定制类型InheritanceType:Hibernate提供3种方式
@ 每个类一张表——TABLE PER CLASS
@ 每个子类一张表——JOINED
@ 每个类层次结构一张表——SINGLE TABLE
每个带隐式多态的具体类一张表:
1、不支持多态关联,因为关联在数据库中被表示为外键约束,对于User与BillingDetails的One2Manny关系无法通过一个外键引用两张表。 2、不同表的不同列具有完全相同的语义,使得数据库范式变得复杂,对于基类属性的改变会影响到子类属性。 3、适用于类层次结构的最顶层,最顶层通常不需要多态。
每个带有联合的具体类一张表——每个类一张表(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、表继承关系表示为相关的外键,声明持久性属性的每个类、子类(抽象、接口)都有自己的表。

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class BillingDetails {
}
@Entity
@PrimaryKeyJoinColumn(name="CREDIT_CARD_ID")
public class extends BillingDetails {
}
//
混合继承策略:把一个类层次结构映射到单张表,但是对于特定的子类,则通过外键映射策略切换到单独的表,就像使用每一个子类一张表一样。

映射集合和实体关联
值类型的set、bag、list、map和组件集合映射(值类型的类——``)
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 bids= new HashSet();
}
// 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、没有CascadeType
Item newItem = new Item();
Bid newBid = new Bid();
newItem.addBid(newBid);
session.save(newItem);
session.save(newBid);
// 2.2、使用CascadeType
Item 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.LAZYOneToOne
ManyToMany:多对多关联始终可以表示为对中间类的两个多对一关联。
会话对象管理持久化管理器:Session、Query、Criteria、Transaction
扩展持久化上下文:每个请求一个会话而不是每个操作一个会话。实现DAO的共享持久化上下文。
通过Hibernate ThreadLocal Session传播通过JTA传播利用Hibernate的对话
利用托管对象的对话。给会话扩展Session,也就是上面两种会话传播。HQL类似于SQL:这两者的区别在于HQL使用类名称而不是表名称,使用属性名称而不是列名称。它可以理解继承——可使用超类、接口查询。
对象获取
导航对象图通过标识符获取 HQL sql