jpa是什么api
作为规范, Java Persistence API与persistence有关,它宽松地表示Java对象在创建它们的应用程序进程中不存在的任何机制。 并非所有Java对象都需要保留,但是大多数应用程序都可以保留关键业务对象。 JPA规范使您可以定义应保留哪些对象,以及如何在Java应用程序中保留这些对象。
JPA本身不是工具或框架; 相反,它定义了可以由任何工具或框架实施的一组概念。 尽管JPA的对象关系映射(ORM)模型最初是基于Hibernate的 ,但此后一直在发展。 同样,尽管JPA最初旨在与关系/ SQL数据库一起使用,但某些JPA实现已扩展为与NoSQL数据存储一起使用。 EclipseLink是支持JPA和NoSQL的流行框架,它是JPA 2.2的参考实现。
雅加达EE中的JPA 2.2
Java Persistence API作为Java EE 5中EJB 3.0规范( JSR 220 )的子集首次发布,自Java EE 6( JSR 317 )中的JPA 2.0发行以来,它已发展成为自己的规范。 在撰写本文时,JPA 2.2已作为Jakarta EE的一部分被采用作为延续 。
JPA和Hibernate
由于它们的历史交织在一起,Hibernate和JPA经常合并在一起。 但是,就像Java Servlet规范一样,JPA产生了许多兼容的工具和框架。 Hibernate只是其中之一。
Hibernate由Gavin King开发并于2002年初发布,是Java的ORM库。 King开发了Hibernate来替代实体bean,以实现持久性 。 该框架是如此流行,并且在当时非常需要,以至于它的许多思想在第一个JPA规范中被采用和整理。
今天, Hibernate ORM是最成熟的JPA实现之一,并且仍然是Java中ORM的流行选择。 Hibernate ORM 5.3.8 (撰写本文时为当前版本)实现了JPA 2.2。 此外,Hibernate的工具系列已扩展到包括流行的工具,例如Hibernate Search , Hibernate Validator和Hibernate OGM ,它们支持NoSQL的域模型持久性。
JPA和EJB
如前所述, JPA是作为EJB 3.0的一个子集引入的 ,但此后又发展成为其自己的规范。 EJB是一个与JPA重点不同的规范,并且是在EJB容器中实现的。 每个EJB容器都包含一个持久层,由JPA规范定义。
什么是Java ORM?
尽管它们的执行有所不同,但是每个JPA实现都提供某种ORM层。 为了了解JPA和兼容JPA的工具,您需要对ORM有很好的了解。
对象关系映射是一项任务 -开发人员有充分的理由避免手动执行此任务 。 诸如Hibernate ORM或EclipseLink之类的框架将该任务编码为一个库或框架,即ORM层 。 作为应用程序体系结构的一部分,ORM层负责管理软件对象的转换,以与关系数据库中的表和列进行交互。 在Java中,ORM层转换Java类和对象,以便可以在关系数据库中存储和管理它们。
默认情况下,要保留的对象的名称将成为表的名称,而字段将成为列。 一旦建立了表,每个表行都对应于应用程序中的一个对象。 对象映射是可配置的,但是默认设置往往可以正常工作。
JPA与NoSQL
直到不久以前,非关系数据库还鲜为人知。 NoSQL运动改变了这一切,现在Java开发人员可以使用各种NoSQL数据库。 一些JPA实现已经演变为包含NoSQL,包括Hibernate OGM和EclipseLink 。
图1说明了JPA和ORM层在应用程序开发中的作用。
![JavaWorld>持久性[系列]>图](https://images.idgesg.net/images/article/2019/04/jw_java_persistence_series_1200x1600_diagram-100792564-large.jpg)
图1. JPA和ORM层
配置Java ORM层
设置新项目以使用JPA时,需要配置数据存储和JPA提供程序。 您将配置一个数据存储连接器以连接到您选择的数据库(SQL或NoSQL)。 您还将包括并配置JPA提供程序 ,它是Hibernate或EclipseLink之类的框架。 虽然您可以手动配置JPA,但是许多开发人员选择使用Spring的现成支持。 有关手动和基于Spring的JPA安装和设置的演示,请参见下面的“ JPA安装和设置 ”。
Java数据对象
Java数据对象是一个标准化的持久性框架,它与JPA的不同之处主要在于,它支持对象中的持久性逻辑,以及其长期支持使用非关系数据存储。 JPA和JDO非常相似,因此JDO提供程序经常也支持JPA。 请参阅Apache JDO项目 ,以了解有关JDO与其他持久性标准(如JPA和JDBC)的更多信息。
Java中的数据持久性
从编程的角度看,ORM层是一个适配器层 :它使对象图的语言适应SQL和关系表的语言。 ORM层允许面向对象的开发人员构建持久化数据的软件,而无需离开面向对象的范例。
使用JPA时,将创建从数据存储区到应用程序的数据模型对象的映射 。 您无需定义对象的保存和检索方式,而是定义对象与数据库之间的映射,然后调用JPA来持久化它们。 如果您使用的是关系数据库,那么应用程序代码与数据库之间的大部分实际连接将由JDBC( Java数据库连接API)处理 。
作为规范,JPA提供了元数据注释 ,您可以使用它们来定义对象与数据库之间的映射。 每个JPA实现都为JPA注释提供了自己的引擎。 JPA规范还提供了PersistanceManager
或EntityManager
,它们是与JPA系统联系的关键点(其中您的业务逻辑代码告诉系统如何处理映射的对象)。
为了使所有这些更加具体,请考虑清单1,它是用于建模音乐家的简单数据类。
清单1. Java中的一个简单数据类
public class Musician {
private Long id;
private String name;
private Instrument mainInstrument;
private ArrayList performances = new ArrayList<Performance>();
public Musician( Long id, String name){ /* constructor setters... */ }
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setMainInstrument(Instrument instr){
this.instrument = instr;
}
public Instrument getMainInstrument(){
return this.instrument;
}
// ...Other getters and setters...
}
清单1中的Musician
类用于保存数据。 它可以包含原始数据,例如名称字段。 它还可以保持与其他类的关系,例如mainInstrument
和performances
。
Musician
的原因是要包含数据。 这种类型的类有时称为DTO或数据传输对象 。 DTO是软件开发的常见功能。 尽管它们保存多种数据,但它们不包含任何业务逻辑。 持久数据对象是软件开发中普遍存在的挑战。
JDBC的数据持久性
将Musician
类的实例保存到关系数据库的一种方法是使用JDBC库。 JDBC是一个抽象层,它使应用程序可以在不考虑基础数据库实现的情况下发出SQL命令。
清单2显示了如何使用JDBC持久化Musician
类。
清单2. JDBC插入记录
Musician georgeHarrison = new Musician(0, "George Harrison");
String myDriver = "org.gjt.mm.mysql.Driver";
String myUrl = "jdbc:mysql://localhost/test";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(myUrl, "root", "");
String query = " insert into users (id, name) values (?, ?)";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt (1, 0);
preparedStmt.setString (2, "George Harrison");
preparedStmt.setString (2, "Rubble");
preparedStmt.execute();
conn.close();
// Error handling removed for brevity
清单2中的代码是完全自我记录的。 georgeHarrison
对象可以来自任何地方(前端提交,外部服务等),并且已设置其ID和名称字段。 然后,对象上的字段用于提供SQL insert
语句的值。 ( PreparedStatement
类是JDBC的一部分,提供了一种将值安全地应用于SQL查询的方法。)
尽管JDBC允许使用手动配置进行控制,但与JPA相比,它比较麻烦。 为了修改数据库,您首先需要创建一个SQL查询,该查询从Java对象映射到关系数据库中的表。 然后,只要对象签名更改,就必须修改SQL。 使用JDBC,维护SQL本身就是一项任务。
使用JPA的数据持久性
现在考虑清单3,我们使用JPA保留了Musician
类。
清单3.坚持使用JPA的George Harrison
Musician georgeHarrison = new Musician(0, "George Harrison");
musicianManager.save(georgeHarrison);
清单3用单行session.save()
替换了清单2中的手动SQL,它指示JPA持久化对象。 从那时起,SQL转换由框架处理,因此您不必离开面向对象的范例。
JPA中的元数据注释
清单3中的神奇之处是配置的结果,该配置是使用JPA的注释创建的。 开发人员使用批注来通知JPA哪些对象应该保留,以及它们应该如何保留。
清单4显示了带有单个JPA批注的Musician
类。
清单4. JPA的@Entity批注
@Entity
public class Musician {
// ..class body
}
持久性对象有时称为实体 。 将@Entity
附加到诸如Musician
类的类时,将通知JPA该类及其对象应保留。
XML与基于注释的配置
JPA还支持使用外部XML文件(而不是注释)来定义类元数据。 但是为什么要自己动手呢?
配置JPA
像大多数现代框架一样,JPA包含按约定编码 (也称为配置约定),其中该框架根据行业最佳实践提供默认配置。 作为一个示例,默认情况下,名为Musician
的类将映射到名为Musician的数据库表。
常规配置是节省时间的,并且在许多情况下它运行良好。 也可以自定义您的JPA配置。 例如,可以使用JPA的@Table
批注指定应该存储Musician
类的表。
清单5. JPA的@Table批注
@Entity
@Table(name="musician")
public class Musician {
// ..class body
}
清单5告诉JPA将实体(“ Musician
类)持久化到“ musician
表中。
首要的关键
在JPA中, 主键是用于唯一标识数据库中每个对象的字段。 主键对于将对象引用和关联到其他实体很有用。 每当将对象存储在表中时,您还将指定要用作其主键的字段。
在清单6中,我们告诉JPA哪个字段用作Musician
的主键。
清单6.指定主键
@Entity
public class Musician {
@Id
private Long id;
在这种情况下,我们使用了JPA的@Id
批注将id
字段指定为Musician
的主键。 默认情况下,此配置假定数据库将设置主键-例如,当字段在表上设置为自动增量时。
JPA支持其他用于生成对象主键的策略。 它还具有用于更改各个字段名称的注释。 通常,JPA足够灵活,可以适应您可能需要的任何持久性映射。
CRUD操作
将类映射到数据库表并建立其主键后,您便拥有了在数据库中创建,检索,删除和更新该类所需的一切。 调用session.save()
将创建或更新指定的类,具体取决于主键字段为null还是适用于现有实体。 调用entityManager.remove()
将删除指定的类。
JPA中的实体关系
简单地使用原始字段持久化对象只是等式的一半。 JPA还具有管理彼此关联的实体的能力。 表和对象中可能有四种实体关系:
- 一对多
- 多对一
- 多对多
- 一对一
每种关系类型都描述一个实体与其他实体的关系。 例如,“ Musician
实体可以与“ Performance
(由诸如List
或Set
的集合表示的实体) 一对多的关系 。
如果“ Musician
包含“ Band
字段,则这些实体之间的关系可能是多对一的 ,这意味着在单个Band
类上Musician
的集合。 (假设每个音乐家只在一个乐队中表演。)
如果Musician
包括BandMates
字段,则该字段可能表示与其他Musician
实体之间的多对多关系 。
最后, Musician
可能与Quote
实体具有一对一的关系 ,用来表示一个著名的Quote famousQuote = new Quote()
: Quote famousQuote = new Quote()
。
定义关系类型
JPA为其每种关系映射类型都有注释。 清单7显示了如何注释Musician
和Performance
之间的一对多关系。
清单7.注释一对多关系
翻译自: https://www.infoworld.com/article/3379043/what-is-jpa-introduction-to-the-java-persistence-api.html
jpa是什么api