JPA即Java Persistence Architecture,Java持久化规范,从EJB2.x版本中原来的实体Bean分离出来的,EJB3.x中不再有实体Bean,而是将实体Bean放到JPA中来实现。可以说,JPA借鉴了Hibernate的设计,JPA的设计者就是Hibernate框架的作者。
JPA的底层实现是一些流行的ORM框架,比如Hibernate,EclipseLink,OpenJPA等实现方式。
(参考http://blog.javachen.com/2014/12/02/some-usages-of-jpa/,并根据实际使用进行了总结)
EntityManagerFactory作为EntityManager的工厂类,创建并管理多个EntityManager实例;EntityManager接口管理持久化操作的对象,其中包含了对实体(Entity,存储在数据库中的记录对象表示)的所有增删改查操作。
EntityManagerFactory是一个spi实现的工厂类,可以创建多个不同的EntityManager;每个EntityManager中只有一个EntityTransaction实例,但可以创建多个不同的Query实例,并执行查询,管理多个Entity实体。
JPA中比较核心的配置文件是persistence.xml文件,基本样式如下:
<?xml version="1.0"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="hsqldb-unit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.username" value="sa"/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/test"/> <property name="hibernate.max_fetch_depth" value="3"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.jdbc.fetch_size" value="18"/> <property name="hibernate.jdbc.batch_size" value="10"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> </properties> </persistence-unit> </persistence>
本例程中使用了Hibernate3.6作为JPA的实现,并以hsqldb作为测试数据库进行配置,在使用Spring容器的场景下通过下面的配置方式进行设置:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdaptor"/> <property name="packagesToScan" value="xxx"/> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/> </property> <property name="persistenceXmlLocation" value="/WEB-INF/config/persistence.xml"/> </bean> <bean id="hibernateJpaVendorAdaptor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect"/> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean>
JPA的持久化映射的数据表
作为ORM框架,肯定是有一套对应Java对象实体到关系数据库映射的工具。在Hibernate诞生之初使用的是.hibernate.xml配置文件的方式,而最近通过注解工具的发展(Annotation,@),已经可以通过更便于管理的方式定义这种关系(当然还可以采取更加灵活的注解+配置文件的混合方式)。
使用@Entity来标识一个持久化对象,所有对应数据库表的持久化对象都必须声明该注解,并可以定义name字段的名称来自定义数据表的内容。
使用@Id来标识主键,持久化对象必须含有主键,主键一般使用与业务无关的自增/随机字段来表示(不建议使用联合主键的方式),以获得更好的扩展性。
可以使用@GenerateValue方式来声明主键自动生成的策略,有下面四种方式:
- GenerationType.TABLE:使用独立表来记录主键,适用于各种数据库,但性能会差一些,因其每次进行insert时都会额外发出一次主键查询;
- GenerationType.SEQUENCE:只适用于oracle数据库;
- GenerationType.IDENTITY:适用于Sqlserver等数据库;
- GenerationType.AUTO:由JPA实现来探测底层使用的数据库,自动采取一种主键自增的策略,可以指定生成器。如对Oracle采用SEQUENCE策略,对Sqlserver采用IDENTITY策略。AUTO策略支持目前绝大多数已知的数据库,这是默认的策略也是我们目前采用的策略。
如果使用AUTO,最好将主键字段设置为long(int也可以);如果设置为generator=uuid,那么主键字段类型使用String;如果不设置@GenerationType,那么应用程序中需要指定主键。
在@Entity对象中定义的所有成员变量,都会映射到数据表中(默认名称即为该字段的名称),可以使用@Column注解显示地将该成员变量定义为数据表字段,并通过name字段显示地指定该字段的名称;也可以使用@Transient来标识该成员变量为非数据库字段;
此外,static(不属于具体的对象实例)或final(不能更改其引用)字段由于其特殊性,并不能作为数据库字段。
如果字段需要使用Java中的枚举类型,可以将字段设置为Enum类型,并设置@Enumerated,如果想要将该字段映射为String(枚举表示的String),可以将其value设置为EnumType.String。
对于想要设置为日期Date类型的字段,可以使用@Temporal来标识,可以选择Date,Time,TimeStamp(默认,如果不标识,也默认使用TimeStamp)。
对于大的文本,想要使用数据库中的Clob或Blob字段,那么可以使用@Lob来标识:
- Clob:java.lang.String, java.lang.Character[],java.lang.char[], java.sql.Clob可映射为Clob;
- Blob:java.lang.byte[], java.lang.Byte[], java.sql.Blob及实现了Serializable对象的类可映射为Blob。
数据表之间的关联关系映射
数据表之间的关联关系在JPA中有三种:
@OneToOne
一对一映射分为主键关联和外键关联两种方式,如果使用主键关联,那么从表的的主键同时也是外键,主从表中关联的记录主键完全一致,需要在被维护端使用@PrimaryKeyJoinColumn指定对应的关系,比如下面的例子:
@Entity public class Husband { @Id @GeneratedValue private Long id; private String name; @OneToOne(mappedBy="husband", cascade=CascadeType.ALL) private Wife wife; ... }
@Entity public class Wife { @Id private Long id; private String name; @OneToOne(cascade=CascadeType.ALL) @PrimaryKeyJoinColumn @MapsId private Husband husband; }
如果是外键关联,则会使用一个额外的外键字段来建立关联关系,比如下面的例子:
@Entity public class Car { @Id @GeneratedValue private Long id; private String name; @OneToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.LAZY) @JoinColumn(name="engine_id")//外键关联字段 private Engine engine; @Entity public class Engine { @Id @GeneratedValue private Long id; private String name; @OneToOne(mappedBy="engine", fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE}) private Car car; }
@OneToMany @ManyToOne
一对多/多对一映射注解,在双向一对多关系中,一端是关系维护端,只能在另一端中添加mapped属性,多端是关系被维护端,建表时在关系被维护端(多的那一端)中建立一个外键指向关系维护端的主键一列。
比如:
@OneToMany(mappedBy = "executableSubTaskDefinition", fetch = FetchType.LAZY) private List<ExecutableSubTaskStatus> executableSubTaskStatusList = new ArrayList<>();
注意,mappedBy即为ExecuteableSubTaskStatus中的@ManyToOne成员变量名称而非数据库字段名称,那么在另一端,
@ManyToOne(cascade = CascadeType.ALL, optional = false) private ExecutableSubTaskDefinition executableSubTaskDefinition;
@ManyToMany
多对多映射是相对来说最为复杂的一种映射关系,会采取中间表连接的映射策略,建立的中间表分别引入两边的主键作为外键,形成两个一对多关系。
在双向的多对多关系中,在关系维护端(owner side)的 @ManyToMany 注解中添加 mappedBy 属性,另一方是关系的被维护端(inverse side),关系的被维护端不能加 mappedBy 属性,建表时,根据两个多端的主键生成一个中间表,中间表的外键是两个多端的主键:
关系维护端——> @ManyToMany(mappedBy="另一方的关系引用属性")
关系被维护端——> @ManyToMany(cascade=CascadeType.ALL ,fetch = FetchType.Lazy)
比如下面的实例:
@ManyToMany @JoinColumn(name = "task_data_range") private List<SubTaskDefinition> subTaskDefinitions = new ArrayList<>();
@ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "sub_task_data_range", joinColumns = @JoinColumn(name = "sd_task_id", referencedColumnName = "sub_task_definition_id"), inverseJoinColumns = @JoinColumn(name = "sd_data_id", referencedColumnName = "task_data_range_id")) private List<TaskDataRange> taskDataRanges = new ArrayList<>();
相关推荐
JPA基本概念 ##### 3.1 EntityManager `EntityManager`是JPA的核心接口之一,用于执行持久化操作,如保存、删除、更新实体对象以及执行查询等。 ##### 3.2 底层事务控制 JPA支持两种类型的事务管理方式:容器...
- **查询创建**:介绍了使用 JPA 标准查询语法创建查询的方法。 - **使用 JPA 命名查询**:说明了如何利用 JPA 命名查询特性。 - **使用 @Query 注解**:讲解了如何使用 @Query 注解自定义查询。 - **使用命名...
### JPA基本概念实例操作详解 #### EntityManager与基本概念 - **EntityManager简介**:`EntityManager`,也称为实体管理器,是Java Persistence API (JPA) 中的核心接口之一,负责处理实体对象的生命周期管理和...
### JPA基本描述 JPA(Java Persistence API)是一种用于管理关系型数据库对象的标准API,它使得Java开发人员能够以面向对象的方式操作数据库。通过提供一套标准的数据持久化规范,JPA大大简化了数据访问层的开发...
1. **JPA概述**:介绍JPA的基本概念和目标,对比JPA与其他ORM工具(如Hibernate)的差异。 2. **实体管理**:讲解实体的声明、生命周期(新、持久、托管、脱管)以及如何通过EntityManager进行操作。 3. **持久化...
1. JPA基本概念和工作原理的概述。 2. JPA的主要组件和接口的详细说明。 3. JPA注解的全面介绍,包括如何使用它们来定义实体类、字段属性以及关系映射。 4. Oracle数据库与JPA的集成,包括驱动配置、数据源设置等。 ...
### 详细介绍 JPA 开发文档 #### 一、发展中的持久化技术 ##### 1.1 JDBC 在早期的企业级应用程序开发中,JDBC (Java Database Connectivity) 是一种广泛使用的数据库连接技术。JDBC 提供了一种标准的方式来访问...
JPA允许使用`@PrePersist`、`@PostPersist`、`@PreUpdate`、`@PostUpdate`、`@PreRemove`和`@PostRemove`等注解定义实体的监听器,实现对象状态改变时的自定义逻辑。 ### 7. 拦截器 JPA通过实现`EntityListener`...
本教程将详细介绍 Spring Data JPA 的核心概念与使用方法,帮助开发者从基础入门到实现复杂查询的完整过程。 第一章:Spring Data JPA 入门 Spring Data JPA 简化了 JPA(Java Persistence API)的开发,通过约定...
本资料主要针对JPA的使用进行详细讲解,包括如何搭建JPA开发环境以及全局事务的介绍。 **一、JPA开发环境的搭建** 1. **集成环境选择**: JPA可以与多种应用服务器和IDE集成,如Tomcat、Jetty、Eclipse、IntelliJ ...
它可能详细介绍了如何定义实体类、配置数据源、创建实体管理器,以及如何使用JPQL进行查询。此外,还可能涉及了JPA的高级特性,如 Criteria 查询、实体监听器、复合主键、转换和验证等。 总的来说,这个压缩包提供...
本书《Pro JPA 2版》是一部深入介绍JPA2的权威书籍,作者通过全面的内容和细致的讲解,帮助读者掌握JPA的核心概念以及其在企业级应用中的实践方法。 从给定的部分内容中,我们可以总结出以下知识点: 1. JPA2架构...
#### 一、Spring-data-jpa 基本介绍 Spring-data-jpa 是 Spring 家族中的一个重要成员,它主要用于简化基于 Java Persistence API (JPA) 的数据访问层(DAO)的开发工作。JPA 作为 Java 平台的一种标准,旨在为 ...
了解以上基础后,你可以观看"03_传智播客JPA详解_搭建JPA开发环境和全局事务介绍"的自学视频,视频将更深入地展示如何操作和实践。学习过程中,你将看到如何配置JPA环境,创建并管理实体,以及如何在实际项目中运用...
1. **JPQL基础**:讲解JPQL的基本语法,包括如何选择、从哪个实体中选择、以及如何使用WHERE子句过滤结果。比如,`SELECT e FROM Entity e` 就是一个基本的查询所有Entity实例的JPQL语句。 2. **聚合函数**:介绍...
**JPA.ppt**可能是一个PowerPoint演示文稿,详细介绍了JPA的基本概念、使用方法和示例。它可能会包含图表、代码片段和逐步指导,帮助初学者理解JPA的工作原理。 **JPA.rar**可能是一个压缩文件,包含了项目示例、源...
- 对于JPA的单元测试,通常会使用模拟库如Hibernate Test或Mockito来隔离数据库交互,避免在测试中真正执行数据库操作。 - 测试Entity的创建,验证save()方法是否能正确地将对象持久化到数据库。 - 测试查询,...
核心概念部分(Core concepts)涵盖了Spring Data JPA的基本概念,例如使用仓库(Repositories)、定义仓库接口、实体映射、查询方法的定义与配置等。Spring Data JPA通过约定优于配置的原则,让我们只需要定义接口...
JPA 详解,详细介绍了JPA的使用,从基本概念到具体例子