什么是JPA?
JPA只是一种规范(Java EE规范的子规范),JPA并不提供实现。
——这意味着开发者底层自由地选择任意的ORM框架。
从使用价值来说,大家都应该面向JPA编程,而不是面向Hibernate。
使用JPA的好处:应用程序可以完全与具体的ORM框架分离开,但底层可以使用任意的ORM框架。
但在实际公司中,由于Hibernate出现的时间远远早于JPA
所有Hibernate早早地占领了开发者市场。
学起来非常简单!
它的本质是ORM规范。
与Hibernate的ORM思想是完全一样: 表 映射 类
列 映射 属性
记录 映射 对象
JPA的开发:
(1) 开发实体类。
JPA的实体类,完全可以在Hibernate中使用。
实体类 = POJO + @Annotation
(2) 需要在classes目录下(对应src目录)新建一个META-INF/persistence.xml配置文件
(类似于Hibernate的hibernate.cfg.xml)
该文件用于管理与数据库的连接。
(3) 在应用程序中使用JPA的API来操作持久化类。
JPA Hibernate
Persistence - Configuration
EntityManagerFactory - SessionFactory
EntityManager - Session
EntityManagerFactory emf = Persistence.createEntityManagerFactory("qs");
EntityManager em = emf.createEntityManager();
对实体的管理:
C
persist
R
find(Class , id) - 类似于Hibernate的Get
getReference - 类似于Hibernate的load
U
merge(T entity) - 类似Hibernate的update
D
remove(entity) - 类似于Hibernate的delete
基本映射:
@Entity - 修饰一个实体类。
@Table - 指定映射的表名。
@Id - 修饰标识属性
@Column - 指定映射的列名
@GeneratedValue - 指定主键生成策略。
对于JPA,只要是实体类的一个属性,即使不用任何Annotation修饰,它会自动完成映射。
@Transient - 修饰某个属性,让它不映射到指定的数据列。
Java的Date类型值,既有日期部分,也有时间部分。
但数据库的列,可能有的只保存时间,有的可能只保存日期。
@Temporal - 指定某个数据列只保存日期、或只保存时间。
可以把一个实体映射到多表(竖切)
@SecondaryTable(name="user_detail"
,pkJoinColumns=@PrimaryKeyJoinColumn(name="user_id"))
并且使用@Column修饰属性时,指定table属性即可表明将该属性映射的列放到另一个表中。
组件映射
使用如下Annotation修饰组件类即可。
@Embeddable - 修饰组件类。(如 User 类含 Address 类型的属性,用@Embeddable 修饰即可)
复合主键映射
A。 以一个复合类作为主键。
该复合类需要实现Serializable接口。建议重写它的equals和hashCode方法
需要使用@EmbededId修饰复合类。
如果你要重定义复合类的子属性对应的列名,用@Column修饰。
B。 直接以持久化类的多个属性作为联合主键。
该持久化类需要实现Serializable接口。建议重写它的equals和hashCode方法
直接以@Id修饰多列即可。
关联映射
单向关联
1 → N
N → 1
1 → 1
N → N
mappedBy属性,有点类似于Hibernate里的inverse="true",
—— 指定了该属性之后,意味着该实体不能控制关联关系。
双向关联
1 - N
@OneToMany(默认是延迟加载)
@ManyToOne(默认是立即加载)
在N的一端使用@JoinColumn来指定外键列的列名。
A。 保存时,先保存主表记录。
B。 应该通过从表记录来控制关联关系。
因此可以在@OneToMany中指定mappedBy属性,
指定了该属性之后,意味主表实体不能控制关联关系。
C。 传播持久化。
1-1
两边都用@OneToOne
任意选择一方使用@JoinColumn修饰,该Annotation用于增加外键列。
N-N
两边都用@ManyToMany
需要在没有指定mappedBy属性一端使用@JoinTable映射连接表。
继承映射
都需要在父类中使用@Inheritance修饰,该Annotation用于指定使用何种映射策略。
默认就是“整个继承树所有记录都放在一个表”。
SINGLE_TABLE
subclass - 整个继承树所有记录都放在一个表。
好处:性能最好。无论什么查询,只需要在一个表中完成。
坏处:将很多null值,而且子类增加的属性映射的列不能有not-null约束。
要增加辨别列,不同类为辨别列指定不同的值。
必须用@DiscriminatorColumn修饰,用于声明辨别列。
JOINED
joined-subclass - 竖切
好处:没有null值,子类增加的属性映射的列可以有not-null约束。
坏处:经常执行多表连接,性能最差。
要增加外键列,来记录各条记录之间的关联关系。
只要使用@Inheritance(strategy=InheritanceType.JOINED)修饰父类即可。
TABLE_PER_CLASS
union-subclass - 横切
好处:没有null值,子类增加的属性映射的列可以有not-null约束。
坏处:执行多态查询时,需要进行union运算。
而且不能使用identity的主键生成策略。
只要使用@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)修饰父类即可。
@TableGenerator —— 用于定义一个基于表的主键生成器。
JPA只是一种规范(Java EE规范的子规范),JPA并不提供实现。
——这意味着开发者底层自由地选择任意的ORM框架。
从使用价值来说,大家都应该面向JPA编程,而不是面向Hibernate。
使用JPA的好处:应用程序可以完全与具体的ORM框架分离开,但底层可以使用任意的ORM框架。
但在实际公司中,由于Hibernate出现的时间远远早于JPA
所有Hibernate早早地占领了开发者市场。
学起来非常简单!
它的本质是ORM规范。
与Hibernate的ORM思想是完全一样: 表 映射 类
列 映射 属性
记录 映射 对象
JPA的开发:
(1) 开发实体类。
JPA的实体类,完全可以在Hibernate中使用。
实体类 = POJO + @Annotation
(2) 需要在classes目录下(对应src目录)新建一个META-INF/persistence.xml配置文件
(类似于Hibernate的hibernate.cfg.xml)
该文件用于管理与数据库的连接。
(3) 在应用程序中使用JPA的API来操作持久化类。
JPA Hibernate
Persistence - Configuration
EntityManagerFactory - SessionFactory
EntityManager - Session
EntityManagerFactory emf = Persistence.createEntityManagerFactory("qs");
EntityManager em = emf.createEntityManager();
对实体的管理:
C
persist
R
find(Class , id) - 类似于Hibernate的Get
getReference - 类似于Hibernate的load
U
merge(T entity) - 类似Hibernate的update
D
remove(entity) - 类似于Hibernate的delete
基本映射:
@Entity - 修饰一个实体类。
@Table - 指定映射的表名。
@Id - 修饰标识属性
@Column - 指定映射的列名
@GeneratedValue - 指定主键生成策略。
对于JPA,只要是实体类的一个属性,即使不用任何Annotation修饰,它会自动完成映射。
@Transient - 修饰某个属性,让它不映射到指定的数据列。
Java的Date类型值,既有日期部分,也有时间部分。
但数据库的列,可能有的只保存时间,有的可能只保存日期。
@Temporal - 指定某个数据列只保存日期、或只保存时间。
可以把一个实体映射到多表(竖切)
@SecondaryTable(name="user_detail"
,pkJoinColumns=@PrimaryKeyJoinColumn(name="user_id"))
并且使用@Column修饰属性时,指定table属性即可表明将该属性映射的列放到另一个表中。
组件映射
使用如下Annotation修饰组件类即可。
@Embeddable - 修饰组件类。(如 User 类含 Address 类型的属性,用@Embeddable 修饰即可)
复合主键映射
A。 以一个复合类作为主键。
该复合类需要实现Serializable接口。建议重写它的equals和hashCode方法
需要使用@EmbededId修饰复合类。
如果你要重定义复合类的子属性对应的列名,用@Column修饰。
B。 直接以持久化类的多个属性作为联合主键。
该持久化类需要实现Serializable接口。建议重写它的equals和hashCode方法
直接以@Id修饰多列即可。
关联映射
单向关联
1 → N
N → 1
1 → 1
N → N
mappedBy属性,有点类似于Hibernate里的inverse="true",
—— 指定了该属性之后,意味着该实体不能控制关联关系。
双向关联
1 - N
@OneToMany(默认是延迟加载)
@ManyToOne(默认是立即加载)
在N的一端使用@JoinColumn来指定外键列的列名。
A。 保存时,先保存主表记录。
B。 应该通过从表记录来控制关联关系。
因此可以在@OneToMany中指定mappedBy属性,
指定了该属性之后,意味主表实体不能控制关联关系。
C。 传播持久化。
1-1
两边都用@OneToOne
任意选择一方使用@JoinColumn修饰,该Annotation用于增加外键列。
N-N
两边都用@ManyToMany
需要在没有指定mappedBy属性一端使用@JoinTable映射连接表。
继承映射
都需要在父类中使用@Inheritance修饰,该Annotation用于指定使用何种映射策略。
默认就是“整个继承树所有记录都放在一个表”。
SINGLE_TABLE
subclass - 整个继承树所有记录都放在一个表。
好处:性能最好。无论什么查询,只需要在一个表中完成。
坏处:将很多null值,而且子类增加的属性映射的列不能有not-null约束。
要增加辨别列,不同类为辨别列指定不同的值。
必须用@DiscriminatorColumn修饰,用于声明辨别列。
JOINED
joined-subclass - 竖切
好处:没有null值,子类增加的属性映射的列可以有not-null约束。
坏处:经常执行多表连接,性能最差。
要增加外键列,来记录各条记录之间的关联关系。
只要使用@Inheritance(strategy=InheritanceType.JOINED)修饰父类即可。
TABLE_PER_CLASS
union-subclass - 横切
好处:没有null值,子类增加的属性映射的列可以有not-null约束。
坏处:执行多态查询时,需要进行union运算。
而且不能使用identity的主键生成策略。
只要使用@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)修饰父类即可。
@TableGenerator —— 用于定义一个基于表的主键生成器。