JPA

来源:互联网 发布:java泛型的通配符 编辑:程序博客网 时间:2024/05/29 15:58

一、JPA概述

1、定义
Java Persistence API,Java持久化API,定义了对象-关系映射(ORM)以及实体对象持久化的标准接口。

2、特点
JPA作为POJO持久化的标准规范,可以脱离容器独立运行,开发和测试更加方便。

3、JPA在应用中的位置
这里写图片描述

4、JPA内容
JPA维护一个Persistence Context(持久化上下文),在持久化上下文中维护实体的生命周期。主要包含三个方面的内容:
(1)ORM元素。JPA支持annotion或xml两种形式描述对象-关系映射。
(2)实体操作API。实现对实体对象的CRUD操作。
(3)查询语言。约定了面向对象的查询语言JPQL(Java Persistence Query Language)。

JPA与hibernate的对比

org.hibernate javax.persistence 说明 cfg.Configuration Persistence 读取配置信息 SessionFactory EntityManagerFactory 用于创建会话/实体管理器的工厂类 Session EntityManager 提供实体操作API,管理事务、创建查询 Transaction EntityTransaction 管理事务 Query Query 执行查询


javax.persistence

二、生命周期

实体生命周期是JPA中非常重要的概念,描述了实体对象从创建到受控、从删除到游离的状态变换。对实体的操作主要就是改变实体的状态。

这里写图片描述

1、New
新创建的实体对象,没有主键(identity)值。

2、Managed
对象处于Persistence Context(持久化上下文)中,被EntityManager管理。

3、Detached
对象已经游离到Persistence Context之外,进入Application Domain

4、Removed
实体对象被删除。

EntityManager提供一系列的方法管理实体对象的生命周期,包括:
persist,将新创建的或已删除的实体转变为Managed状态,数据存入数据库。
remove,删除受控实体。
merge,将游离实体转变为Managed状态,数据存入数据库。

如果使用了事务管理,则事务的commit/rollback也会改变实体的状态。

三、实体关系映射(ORM)

1、基本映射

对象端 数据库端 annotion 可选 annotion Class Table @Entity @Table(name=”table name”) property column - @Column(name=”column name”) property primary key @Id @GeneratedValue property NONE @Transient

ID对应数据库表的主键,是保证唯一性的重要属性。JPA提供了以下几种ID生成策略
(1)GeneratorType.AUTO ,由JPA自动生成
(2)GenerationType.IDENTITY,使用数据库的自增长字段,需要数据库的支持(如SQL Server、MySQL、DB2、Derby等)
(3)GenerationType.SEQUENCE,使用数据库的序列号,需要数据库的支持(如Oracle)
(4)GenerationType.TABLE,使用指定的数据库表记录ID的增长 需要定义一个TableGenerator,在@GeneratedValue中引用。例如:
@TableGenerator( name=”myGenerator”, table=”GENERATORTABLE”, pkColumnName = “ENTITYNAME”, pkColumnValue=”MyEntity”, valueColumnName = “PKVALUE”, allocationSize=1 )
@GeneratedValue(strategy = GenerationType.TABLE,generator=”myGenerator”)

2、ID生成策略
ID对应数据库表的主键,是保证唯一性的重要属性。JPA提供了以下几种ID生成策略
(1)GeneratorType.AUTO ,由JPA自动生成
(2)GenerationType.IDENTITY,使用数据库的自增长字段,需要数据库的支持(如SQL Server、MySQL、DB2、Derby等)
(3)GenerationType.SEQUENCE,使用数据库的序列号,需要数据库的支持(如Oracle)
(4)GenerationType.TABLE,使用指定的数据库表记录ID的增长 需要定义一个TableGenerator,在@GeneratedValue中引用。例如:
@TableGenerator( name=”myGenerator”, table=”GENERATORTABLE”, pkColumnName = “ENTITYNAME”, pkColumnValue=”MyEntity”, valueColumnName = “PKVALUE”, allocationSize=1 )
@GeneratedValue(strategy = GenerationType.TABLE,generator=”myGenerator”)

3、关联关系

4、继承关系
JPA通过在父类增加@Inheritance(strategy=InheritanceType.xxx)来声明继承关系。A支持3种继承策略:
(1)单表继承(InheritanceType.SINGLETABLE),所有继承树上的类共用一张表,在父类指定(@DiscriminatorColumn)声明并在每个类指定@DiscriminatorValue来区分类型。
(2)类表继承(InheritanceType.JOINED),父子类共同的部分公用一张表,其余部分保存到各自的表,通过join进行关联。
(3)具体表继承(InheritanceType.TABLEPERCLASS),每个具体类映射到自己的表。
其中1和2能够支持多态,但是1需要允许字段为NULL,2需要多个JOIN关系;3最适合关系数据库,对多态支持不好。具体应用时根据需要取舍。

四、Query Language查询语言

1、JPA提供两种查询方式
(1)一种是根据主键查询,使用EntityManager的find方法:T find(Class entityClass, Object primaryKey)
(2)另一种就是使用JPQL查询语言。JPQL是完全面向对象的,具备继承、多态和关联等特性,和hibernate HQL很相似。使用EntityManager的createQuery方法:Query createQuery(String qlString)

2、使用参数
可以在JPQL语句中使用参数。JPQL支持命名参数和位置参数两种参数,但是在一条JPQL语句中所有的参数只能使用同一种类型。

举例如下:命令参数Query query = em.createQuery("select p from Person p where p.personid=:Id"); query.setParameter("Id",new Integer(1));位置参数Query query = em.createQuery("select p from Person p where p.personid=?1"); query.setParameter(1,new Integer(1));

3、命名查询
如果某个JPQL语句需要在多个地方使用,还可以使用@NamedQuery 或者 @NamedQueries在实体对象上预定义命名查询。在需要调用的地方只要引用该查询的名字即可。

例如:@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1")@NamedQueries({ @NamedQuery(name="getPerson1", query= "FROM Person WHERE personid=?1"), @NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1") })Query query = em.createNamedQuery("getPerson");

4、排序
JPQL也支持排序,类似于SQL中的语法。

例如: Query query = em.createQuery("select p from Person p order by p.age, p.birthday desc")

5、聚合查询
JPQL支持AVG、SUM、COUNT、MAX、MIN五个聚合函数。例如:

Query query = em.createQuery("select max(p.age) from Person p"); Object result = query.getSingleResult(); String maxAge = result.toString();

6、更新和删除
JPQL不仅用于查询,还可以用于批量更新和删除。

Query query = em.createQuery("update Order as o set o.amount=o.amount+10"); //update 的记录数 int result = query.executeUpdate();Query query = em.createQuery("delete from OrderItem item where item.order in(from Order as o where o.amount<100)"); query.executeUpdate();
0 0