jacksun1978

导航

 

 

1、持久化上下文

    持久化单元(persist unit)就是关于一组Entity的命名配置。持久化单元是一个静态概念。

    持久化上下文(Persist Context)就是一个受管的Entity实例的集合。每一个持久化上下文都关联一个持久化单元,持久化上下文不可能脱离持久化单元独立存在。持久化上下文是一个动态概念。

   

    尽管持久化上下文非常重要,但是开发者不直接与之打交道,持久化上下文在程序中是透明的,我们通过EntityManager间接管理它。

 

三个类:Persistence,EntityManagerFactory和EntityManager

独立运行环境下:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPADemoPU");

EntityManager entityManger = emf.createEntityManager();

使用容器的环境下,不需要通过Persistence创建EntityManagerFactory和EntityManger,而是通过注解实现

@PersistenceContext

private EntityManger entityManger;

@PersistenceUnit

private EntityMangerFactory emf;

 

2、容器管理的EntityManager

    通过将@PersistContext注解标注在EntityManager类型的字段上,这样得到的EntityManager就是容器管理的EntityManager,我们不需要也不应该显式的关闭注入的EntityManager实例。

 

    容器管理的EntityManager细分为两种类型:事务类型和扩展类型。如果@PersistContext未指定type属性,或者指定为PersistContextType.TRANSACTION,则表示该类型是事务类型的,如果指定为PersistContextType.EXTENDED,表示该EntityManager是扩展类型的。

 

    事务类型:事务类型的EntityManger是无状态的,可用在无状态会话bean和有状态会话bean。事务类型的EntityManger依赖于JTA,每次调用EntityManager实例的方法时,EntityManager会查看是否某个持久化上下文与当前事务关联,如果有,则使用该持久化上下文,如果没有,EntityManager会创建一个持久化上下文,并将该持久化上下文与当前事务关联,事务结束时持久化上下文消失。

    JPA支持两种类型的事务:本地资源事务(RESOURCE_LOCAL)和JAVA事务API(JTA)

    本地资源事务(RESOUCE_LOCAL):使用JDBC驱动管理的本地事务。

    JAVA事务API(JTA):可用于管理分布式事务,管理多数据源的情况。

    容器管理的EntityManager总是使用JTA事务,应用程序管理的EntityManager可以使用本地资源事务,也可以使用JTA事务:在j2SE环境下默认是本地资源事务,在J2EE环境下,默认是JTA。事务的类型在persistence.xml中定义。

 

    扩展类型:扩展类型的EntityManager只能用于有状态会话Bean。扩展的EntityManager在有状态会话bean实例创建时候创建一个持久化上下文,直到该有状态会话bean销毁时,相应的持久化上下文才被移除。在扩展的EntityManager中,每次方法调用使用的都是相同的持久化上下文,所以前一次方法调用产生的受管实体下一个方法访问时仍然是受管实体。

 

 

实体的生命周期:新实体(new),持久化态(managed),游离态(detached),删除状态(removed)

EntityManger控制实体在四个状态之间转换

 

image

 

image

 

1、void persist(t entity)

    调用persist,新实体状态(new)转化为持久化状态(managed),如果实体已经被持久化,则调用persist方法不会发生任何事情,如果对于一个删除状态的实体调用persist方法,则删除态的实体又转变为持久化态,如果对于一个游离态(detached)的实体执行persist操作,则抛出IllegalArgumentException异常。

    对一个实体执行persist操作,将广播到实体关联的实体上,执行级联化操作。

 

2、void remove(t entity)

    通过调用remove方法删除一个持久化态的实体。如果实体声明为级联删除,则相关联的实体也被删除。

    在一个新实体状态(new)的实体上调用remove操作,将被忽略。

    在游离态的实体上调用remove操作,将抛出IllegalArgumentException异常。

    在删除态的实体上调用remove操作,将被忽略。

 

3、void flush()

    将持久化态的实体数据同步到数据库中。

 

4、<T> T merge(T entity)

    将游离态的实体持久化到数据库中,并转换为持久化态。

    如果A是一个游离态的实体,该方法会将A的修改提交到数据库,并产生一个Managed态的实例A2

    如果A是一个new态的实体,该方法会根据A产生一个managed态的实体A2

    如果A是一个managed态的实体,它的状态不会改变,但是系统仍然会在数据库执行UPDATE操作。

    如果A是remove态的实体,该方法会抛出IllegalArgumentException异常

 

5、void refresh(T entity)

    该方法保证当前的实例与数据库中的实例内容一致。

    如果A是一个new态的实体,该方法不会发生任何操作。

    如果A是一个managed态的实体,它的属性将与数据库中的数据同步。

    如果A是remove态的实体,该方法不会发生任何操作

    如果A是detached态的实体,该方法抛出异常。

6、<T> T find(Class<T> entityClass,Object primaryKey)

    以主键查询实体对象,entityClass是实体的类,primaryKey是主键值,如以下的代码查询Topic实体:
    Topic t = em.find(Topic.class,1);

7、 Query createQuery(String qlString)

    根据JPA的查询语句创建一个查询对象Query

8、Query createNativeQuery(String sqlString)

    使用本地数据库的sql语句创建一个query对象

 

  • 根据JPA规范,persist()、 merge()、remove()操作必须运行在事务环境;
  • 根据JPA规范,find()、getReference()、 refresh()、detach()和查询操作都无需运行在事务环境。
  •  

    Query对象

        JPA使用java.persistence.Query接口代表一个查询实例,Query实例由EntityManager通过指定查询语句构建。

    posted on 2012-03-23 22:45  jacksun1978  阅读(2886)  评论(1编辑  收藏  举报