JPA介绍
JPA(Java Persistence API)是一系列类、方法,用于将大量数据储持久地存到数据库中。
企业级应用中,通过存储和检索大量数据来执行数据库操作。使用JPA,会使与数据库交互的负担大大减少。它在对象模型(Java Objects)和关系模型(数据库程序)之间架起一座桥梁。
关系模型和对象模型之间的不匹配
关系对象以表格的形式表示,而对象模型是以对象格式的相互关系来表示的。在从关系模型中存储和检索一个对象模型时,往往会由于以下的原因发生不匹配:
- 颗粒度:对象关系往往有更细的颗粒度
- 子类型:并非所有关系数据库都支持子类型(继承)
- 特征性:和对象模型一样,关系模型在编写平等性的时候不将特征(identity)暴露
- 关系:关系模型在考察对象模型时无法确定多重关系
- 数据迁移:两种模型中的在对象网络的数据迁移形式不尽相同
类级架构
单元 | 描述 |
---|---|
EntityManagerFactory | EntityManager的工厂类,创建并管理多个EntityManager实例 |
EntityManager | 接口类,管理对象的持久化操作,类似于Query实例的工厂类 |
Entity | 持久性对象,作为记录储存在数据库中 |
EntityTransaction | 与EntityManager为1对1关系,对于每一个EntityManager来说,其操作都由EntityTransaction维护 |
Persistence | 这个类包含了获取EntityManagerFactory实例的静态方法 |
Query | 这个接口由每个JPA供应商实现,以获得符合标准的关系对象 |
对象关系映射
ORM(Object Relational Mapping)是一种将数据从对象类型转换为关系类型的编程能力,反之亦然。
高级特性
- 持久性:让你能够使用面向对象的类来编写持久化的类
- 高性能:有许多检索技术和锁技术
- 健壮性:高度稳定和突出
ORM架构
阶段1
第一阶段 对象数据 包含POJO类,服务接口和类。这是主要的业务组件层,主要处理业务逻辑操作与属性。
例如,一个雇员数据库模式:
- 雇员的Employee POJO包含各种属性例如 ID, name, salary, designation。以及相应的getter/setter
- 雇员的Employee DAO/Service类包含服务方法例如创建、检索、删除employee
阶段2
第二个阶段为 映射 或 持久层 阶段,包含JPA提供者、映射文件(ORM.xml)、JPA加载器和对象网格。
- JPA提供者:包含JPA单元(javax.persistence)的供应商产品,例如Eclipselink、Toplink、Hibernate等
- 映射文件:包含映射POJO类与关系数据库之间数据的配置文件
- JPA加载器:加载关系网格数据的高速缓存,它的作用就像数据库的副本,与POJO类数据的服务类进行数据交互
- 对象网格:对象网格是一个存储关系数据副本的临时场所,类似高速缓存。所有检索语句首先会影响对象网格中的数据。只有它被提交之后,主数据库才会被影响
阶段3
第三个阶段为关系数据阶段。它包含与业务组件有逻辑联系的关系型数据。如上所述,只有业务组件提交了数据之后,才会在主数据库上物理性存储。在那之前,修改的数据会被储存在类似网格格式的高速缓存中。获取数据的情况也类似。
上述三个阶段的程序性互动机制被称为对象关系映射。
Mapping.xml
mapping.xml 文件用于指示供应商将实体类与数据库表进行映射。
以下例子将一个Employee POJO类与数据库表建立映射:
Emloyee.java
public class Employee {
private int eid;
private String ename;
private double salary;
private String deg;
public Employee(int eid, String ename, double salary, String deg) {
super( );
this.eid = eid;
this.ename = ename;
this.salary = salary;
this.deg = deg;
}
public Employee( ) {
super();
}
public int getEid( ) {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getEname( ) {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public double getSalary( ) {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getDeg( ) {
return deg;
}
public void setDeg(String deg) {
this.deg = deg;
}
}
mapping.xml
<? xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<description> XML Mapping file</description>
<entity class="Employee">
<table name="EMPLOYEETABLE"/>
<attributes>
<id name="eid">
<generated-value strategy="TABLE"/>
</id>
<basic name="ename">
<column name="EMP_NAME" length="100"/>
</basic>
<basic name="salary">
</basic>
<basic name="deg">
</basic>
</attributes>
</entity>
</entity-mappings>
-
: 允许在xml文件中使用entity标签
-
: 应用的描述
-
: 定义想要转化为数据库中表的entity类。属性类定义了POJO entity的类名
-
: 定义了表名。如果类名与表名一致,这个标签不必要
-
: 定义表中的字段
-
: 定义了主Key, 定义了如何分配主键值,如自动、手动或取自序列
-
: 定义余下的表属性
-
: 定义用户规定的表字段名
Java Bean 标准
Java类,将实例值和各种行为封装到名为对象的单一单元。Java Bean是一个临时存储可重用的组件/对象。它是一个可序列化的类,有默认的构造函数和getter/setter方法用以单独初始化实例的属性。
Bean公约
- Bean包含默认构造函数或者包含序列化实例的文件,因此,bean可以实例化bean
- Bean的属性可分隔为布尔属性和非布尔属性
- 非布尔属性包含 getter 和 setter 方法
- 布尔属性包含 setter 和 is 方法
- 任何属性的getter方法都应该用属性的驼峰命名法(getProperty)
- 任何属性的setter方法都应该用属性的驼峰命名法(setProperty)