持久化API(JPA)系列(五)控制实体Bean的生命周期


   上篇文章《持久化API(JPA)系列(四)管理器EntityManager--执行数据库更新》中我们讲解了使用实体管理器的各种函数操作数据库的方法。

本文主要讲:控制实体Bean的生命周期。
与会话Bean类似,实体Bean也有自己的生命周期,分别对应不同的状态。

下面我们首先来讲解实体Bean的状态和生命周期事件:
1、实体Bean生命周期的4种状态
2、实体Bean的事件:
    @PostLoad
    @PrePersist和@PostPersist
    @PreUpdate和@PostUpdate
    @PreRemove和@PostRemove。

3、事件回调的两种方法:
    外部回调:编写外部监听器。


=============================================================================
1、实体Bean生命周期的4种状态
实体分为被容器管理和不被容器管理两种。可以通过实体管理器的的两个方法进行检测:
    contains()用来检查实体是否被管理。
    clear()分离实体。



实际上,实体共有4种状态。
   
new--新实体:实体由应用产生,和实体管理器没有任何联系,也没有唯一的标识符。
    managed--持久化实体:新实体和实体管理器产生关联(通过persist()、merge()等方法),在实体管理器中存在和被管理,标志是在实体管理器中有一个唯一的标识符。
    detached--分离的实体:实体有唯一的标识符,但它的标识符不被实体管理器管理。
    removed--删除的实体:实体被remove()方法删除,对应的记录将会在当前事务提交的时候从数据库中删除。

=============================================================================
2、实体Bean生命周期的回调事件
当你在执行各种持久化方法的时候,实体的状态会随之改变,状态的改变会引发不同的生命周期事件。这些事件可以使用不同的注释符来指示发生时的回调函数。
    @PostLoad 加载后
    @PrePersist和@PostPersist 持久化前后
    @PreUpdate和@PostUpdate 更新前后
    @PreRemove和@PostRemove 删除前后

以上的7种事件对应了数据库的4种操作。

1)数据库查询
@PostLoad事件在下列情况下触发:
执行EntityManager.find()或getreference()方法载入一个实体后。
执行JPQL查询后。
EntityManager.refresh()方法被调用后。

2)数据库插入
@PrePersist和@PostPersist事件在实体对象插入到数据库的过程中发生:
@PrePersist事件在调用persist()方法后立刻发生,此时的数据还没有真正插入进数据库。
@PostPersist事件在数据已经插入进数据库后发生。

3)数据库更新

@PreUpdate和@PostUpdate事件的触发由更新实体引起:
@PreUpdate事件在实体的状态同步到数据库之前触发,此时的数据还没有真正更新到数据库。
@PostUpdate事件在实体的状态同步到数据库之后触发,同步在事务提交时发生。

4)数据库删除
@PreRemove和@PostRemove事件的触发由删除实体引起:
@PreRemove事件在实体从数据库删除之前触发,即在调用remove()方法删除时发生,此时的数据还没有真正从数据库中删除。
@PostRemove事件在实体从数据库中删除后触发。

=============================================================================
3、外部回调--编写外部监听器
对于以上7种事件类型,我们可以用两种方法来实现回调。
外部回调:即编写一个实体监听器,实现对某一个实体Bean的回调。
内部回调:通过在实体Bean内部的监听进行回调。


1)外部回调:
A.首先编写一个回调的监听器类,该类需要使用@javax.persistence.EntityListeners注释符绑定目标实体Bean,实现实体Bean的监听。
B.在该类中可以编写多个回调方法,通过在方法前添加不同的回调注释符实现事件的拦截。
C.回调方法需要返回void型值,并且拥有一个Object参数。

这种通过编写外部监听器的方法,类似于AOP的功能,可以通过外部类实现对系统中目标类和函数的监听。
Demo演示

2)内部回调步骤:
A.回调方法写在实体Bean中。直接写在实体Bean中的回调方法不需带任何参数。
B.直接写在实体Bean中的回调方法不需带任何参数。
C.不同的回调函数也是通过回调注释符进行注释来标注的。

Demo演示





你可能感兴趣的:(JPA)