`

Entity Bean (2) : EntityManager [转]

 
阅读更多
Session bean or MD bean对Entity bean的操作(包括所有的query, insert, update, delete操作)都是通过EntityManager实例来完成的。EntityManager是由EJB 容器自动地管理和配置的,不需要用户自己创建。
 
那么Session bean or MD bean如何获得EntityManager实例呢??
非常简单,就是通过下列代码进行依赖注入:
Public class sessionbean1{
@PersistenceContext
EntityManager em;
 。。。
}
 
注意:如果persistence.xml文件中配置了多个<persistence-unit>。那么在注入EntityManager对象时必须指定持久化名称,通过@PersistenceContext注释的unitName属性进行指定,例:
 
@PersistenceContext(unitName="foshanshop")
EntityManager em;
 
如果只有一个<persistence-unit>,不需要明确指定。
 
 
请注意:Entity BeanEntityManager管理时,EntityManager跟踪他的状态改变,在任何决定更新实体Bean的时候便会把发生改变的值同步到数据库中(跟hibernate一样)。但是如果entity BeanEntityManager分离后,他是不受管理的,EntityManager无法跟踪他的任何状态改变
 
 
EntityManager一些常用的API(包含query, insert, update, delete操作)
 
1)get entity —— find() or getReference()
Person person = em.find(Person.class,1);
/*
try {
Person person = em.getReference (Person.class, 1);
} catch (EntityNotFoundException notFound) {
// 找不到记录...
}
*/
当在数据库中没有找到记录时,getReference()find()是有区别的find()方法会返回null,而getReference()方法会抛出javax.persistence.EntityNotFoundException例外另外getReference()方法不保证entity Bean已被初始化。如果传递进getReference()find()方法的参数不是实体Bean,都会引发IllegalArgumentException例外
 
2)insert —— persist()
Person person = new Person();
person.setName(name);
//把数据保存进数据库中
em.persist(person);
 
如果传递进persist()方法的参数不是实体Bean,会引发IllegalArgumentException
 
3)update —— 分2种情况
情况1:当实体正在被容器管理时,你可以调用实体的set方法对数据进行修改,在容器决定flush这个由container自行判断),更新的数据才会同步到数据库,而不是在调用了set方法对数据进行修改后马上同步到数据库如果你希望修改后的数据马上同步到数据库,你可以调用EntityManager.flush()方法
public void updatePerson() {
try {
Person person = em.find(Person.class, 1);
person.setName("lihuoming"); //方法执行完后即可更新数据
} catch (Exception e) {
e.printStackTrace();
}
}
 
 
    情况2:在实体Bean已经脱离了EntityManager的管理时,你调用实体的set方法对数据进行修改是无法同步更改到数据库的。你必须调用EntityManager.merge()方法。调用之后,在容器决定flush这个由container自行判断),更新的数据才会同步到数据库如果你希望修改后的数据马上同步到数据库,你可以调用EntityManager.flush()方法
   
public boolean updatePerson(Person person) {
try {
em.merge(person);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
 
下面的代码会调用上面的方法。因为下面的第二行代码把实体Bean 返回到了客户端,这时的实体Bean已经脱离了容器的管理,在客户端对实体Bean进行修改,最后把他返回给EJB 容器进行更新操作:
 
PersonDAO persondao = (PersonDAO) ctx.lookup("PersonDAOBean/remote");
Person person = persondao.getPersonByID(1); //此时的person 已经脱离容器的管理
person.setName("张小艳");
persondao.updatePerson(person);
 
执行em.merge(person)方法时,容器的工作规则
1>     如果此时容器中已经存在一个受容器管理的具有相同IDperson实例,容器将会把参数person的内容拷贝进这个受管理的实例,merge()方法返回受管理的实例,但参数person仍然是分离的不受管理的。容器在决定Flush时把实例同步到数据库中。
 
2>容器中不存在具有相同IDperson实例。容器根据传进的person参数Copy出一个受容器管理的person实例,同时merge()方法会返回出这个受管理的实例,但参数person仍然是分离的不受管理的。容器在决定Flush时把实例同步到数据库中。
 
如果传递进merge ()方法的参数不是实体Bean,会引发一个IllegalArgumentException
 
 
4)Delete —— Remove()
Person person = em.find(Person.class, 2);
//如果级联关系cascade=CascadeType.ALL,在删除person 时候,也会把级联对象删除。
//cascade属性设为cascade=CascadeType.REMOVE 有同样的效果。
em.remove (person);
 
如果传递进remove ()方法的参数不是实体Bean,会引发一个IllegalArgumentException
 
 
5)HPQL query —— createQuery()
 
除了使用find()getReference()方法来获得Entity Bean之外,你还可以通过JPQL得到实体Bean
 
要执行JPQL语句,你必须通过EntityManagercreateQuery()createNamedQuery()方法创建一个Query 对象
 
Query query = em.createQuery("select p from Person p where p. name=’黎明’");
List result = query.getResultList();
Iterator iterator = result.iterator();
while( iterator.hasNext() ){
//处理Person
}
// 执行更新语句
Query query = em.createQuery("update Person as p set p.name =?1 where p. personid=?2");
query.setParameter(1, “黎明”);
query.setParameter(2, new Integer(1) );
int result = query.executeUpdate(); //影响的记录数
// 执行更新语句
Query query = em.createQuery("delete from Person");
int result = query.executeUpdate(); //影响的记录数
 
 
6)SQL query —— createNaiveQuery()
注意:该方法是针对SQL语句,而不是HPQL语句
 
//我们可以让EJB3 Persistence 运行环境将列值直接填充入一个Entity 的实例,
//并将实例作为结果返回.
Query query = em.createNativeQuery("select * from person", Person.class);
List result = query.getResultList();
if (result!=null){
Iterator iterator = result.iterator();
while( iterator.hasNext() ){
Person person= (Person)iterator.next();
… ..
}
}
// 直接通过SQL 执行更新语句
Query query = em.createNativeQuery("update person set age=age+2");
query.executeUpdate();
 
 
7)Refresh entity —— refresh()
如果你怀疑当前被管理的实体已经不是数据库中最新的数据,你可以通过refresh()方法刷新实体,容器会把数据库中的新值重写进实体。这种情况一般发生在你获取了实体之后,有人更新了数据库中的记录,这时你需要得到最新的数据当然你再次调用find()getReference()方法也可以得到最新数据,但这种做法并不优雅
 
Person person = em.find(Person.class, 2);
//如果此时person 对应的记录在数据库中已经发生了改变,
//可以通过refresh()方法得到最新数据。
em.refresh (person);
 
 
8)Check entity是否在EntityManager管理当中 —— contains()
contains()方法使用一个实体作为参数,如果这个实体对象当前正被持久化内容管理,返回值为true,否则为false。如果传递的参数不是实体Bean,将会引发一个IllegalArgumentException.
 
Person person = em.find(Person.class, 2);
。。。
if (em.contains(person)){
//正在被持久化内容管理
}else{
//已经不受持久化内容管理
}
 
 
9)分离所有当前正在被管理的实体 —— clear()
在处理大量实体的时候,如果你不把已经处理过的实体从EntityManager中分离出来,将会消耗你大量的内存调用EntityManager clear()方法后,所有正在被管理的实体将会从持久化内容中分离出来。有一点需要说明下,在事务没有提交前事务默认在调用堆栈的最后提交,如:方法的返回),如果调用clear()方法,之前对实体所作的任何改变将会掉失,所以建议你在调用clear()方法之前先调用flush()方法保存更改
 
 
10)             将实体的改变立刻刷新到数据库中 —— flush()
EntityManager对象在一个session bean 中使用时,它是和服务器的事务上下文绑定的。EntityManager在服务器的事务提交时提交并且同步它的内容。在一个session bean 中,服务器的事务默认地会在调用堆栈的最后提交(如:方法的返回)
 
例子1:在方法返回时才提交事务
public void updatePerson(Person person) {
try {
Person person = em.find(Person.class, 2);
person.setName("lihuoming");
em.merge(person);
//后面还有众多修改操作
} catch (Exception e) {
e.printStackTrace();
}
//更新将会在这个方法的末尾被提交和刷新到数据库中
}
 
为了只在当事务提交时才将改变更新到数据库中,容器将所有数据库操作集中到一个批处理中,这样就减少了代价昂贵的与数据库的交互。当你调用persist( ), merge( )remove( )这些方法时,更新并不会立刻同步到数据库中,直到容器决定刷新到数据库中时才会执行默认情况下,容器决定刷新是在“相关查询”执行前或事务提交时发生,当然“相关查询”除find()getreference()之外,这两个方法是不会引起容器触发刷新动作的默认的刷新模式是可以改变的,具体请
考参下节
 
如果你需要在事务提交之前将更新刷新到数据库中,你可以直接地调用EntityManager.flush()方法。这种情况下,你可以手工地来刷新数据库以获得对数据库操作的最大控制。
public void updatePerson(Person person) {
try {
Person person = em.find(Person.class, 2);
person.setName("lihuoming");
em.merge(person);
em.flush();//手动将更新立刻刷新进数据库
 
//后面还有众多修改操作
} catch (Exception e) {
e.printStackTrace();
}
}
 
 
11)             改变实体管理器的Flush模式 —— setFlushMode()
 
Flush模式有2种类型:AUTO and COMMIT。AUTO为缺省模式。你可以改变他的值,如下:
entityManager.setFlushMode(FlushModeType.COMMIT);
 
FlushModeType.AUTO刷新在查询语句执行前(除了find()getreference()查询)或事务提交时才发生,使用场合:在大量更新数据的过程中没有任何查询语句(除了find()getreference()查询)的执行。
 
FlushModeType.COMMIT刷新只有在事务提交时才发生,使用场合:在大量更新数据的过程中存在查询语句(除了find()getreference()查询)的执行。
 
其实上面两种模式最终反映的结果是:JDBC 驱动跟数据库交互的次数JDBC 性能最大的增进是减少JDBC 驱动与数据库之间的网络通讯FlushModeType.COMMIT模式使更新只在一次的网络交互中完成,而FlushModeType.AUTO 模式可能需要多次交互(触发了多少次Flush 就产生了多少次网络交互)
 
12)             获取持久化实现者的引用 —— getDelegate()
 
用过getDelegate()方法,你可以获取EntityManager持久化实现者的引用,如Jboss EJB3的持久化产品采用Hibernate,可以通过getDelegate()方法获取对他的访问,如:
HibernateEntityManager manager = (HibernateEntityManager)em.getDelegate();
 
获得对Hibernate的引用后,可以直接面对Hibernate进行编码不过这种方法并不可取,强烈建议不要使用。在Weblogic 中,你也可以通过此方法获取对Kodo 的访问。
分享到:
评论

相关推荐

    EntityManager Demo

    2. **Entity**:在JPA中,实体是与数据库表相对应的Java类。它们通常包含@javax.persistence.Entity注解,并且有一个或多个主键字段。实体类允许开发者定义业务逻辑和属性,JPA则负责将这些对象与数据库交互。 3. *...

    EntityBeanTest

    5. **JPA和ORM**:如果使用JPA,需要理解实体类的定义(@Entity注解)、属性映射(@Column等注解)、主键生成策略(@GeneratedValue)等,以及JPA的Repository接口或EntityManager的使用。 6. **单元测试和集成测试...

    EntityBean配置过程.txt

    ### EntityBean配置过程详解 #### 一、概述 本文档主要介绍了如何在JBoss服务器上配置EntityBean以连接Oracle数据库的过程。重点在于介绍一个表(One Table)模式下的配置细节,包括添加数据源、配置JNDI名称以及...

    EJB3 (一)【开发Entity Bean】

    在本教程中,我们将深入探讨如何开发Entity Bean,这是EJB3中的一个重要组成部分,用于持久化业务数据。** **1. Entity Bean概览** Entity Bean代表应用程序中的持久性对象,它们与数据库中的记录相对应。在EJB3中...

    Enterprise Java beans 3.0 , Fifth Edition

    2. 持久化和实体Bean(Persistence and Entity Beans):详细解释了EJB中的实体Bean如何映射关系型数据库中的表,实体Bean可以代表数据库中的表记录,使得数据库操作可以以对象的方式进行。这部分还包括对实体Bean...

    EntityManager

    在EJB(Enterprise JavaBeans)环境中,Session bean 或 MDB(Message-Driven Bean)与Entity bean交互时,EntityManager是主要的接口,它负责处理Entity bean的所有查询、插入、更新和删除操作。EntityManager实例...

    JPA开发文档--总结

    **JPA 开发文档——全面解析** 1. **发展中的持久化技术** ...通过理解JPA的发展背景、体系架构、Entity Bean的定义和管理,以及EntityManager和JPA查询的使用,开发者能够更高效地实现数据持久化。

    JPA 开发指导文档

    2. **EntityManager**:EntityManager是JPA的接口,它负责与数据库进行交互,提供诸如创建、查找、更新和删除Entity对象的能力。通过EntityManager,开发者可以管理Entity的生命周期,包括持久化、加载、更新、删除...

    详细介绍 jpa 开发文档

    5. **Entity Bean**:在JPA中,Entity Bean代表数据库表的一行记录。开发者可以通过注解方式定义Entity,以及其属性变量的访问策略,如`@Entity`、`@Table`、`@Column`等。 6. **主键和实体标识**:每个Entity Bean...

    EJB实验报告。实验一:使用Session Bean和JDBC技术完成登录和注册功能

    2. 使用@Entity注解将User类声明为Entity Bean,让ORM(对象关系映射)框架自动管理与数据库的交互。 3. 在Session Bean中使用EntityManager进行CRUD(创建、读取、更新、删除)操作。 实验错误及解决方法: - 创建...

    jpa开发手册.doc

    Entity Bean **Entity**是JPA中的核心概念,代表数据库中的一个表。开发者可以定义Entity类,通过注解标记为@Entity,并设置主键(@Id)和其他属性。 - **属性访问控制**:开发者可以选择字段级或getter/setter...

    EntityManager API方法详解

    Session bean or MD bean对Entity bean的操作(包括所有的query, insert, update, delete操作)

    jpa开发手册[文].pdf

    本文档涵盖了JPA的基础知识、JPA的体系架构、Entity Bean的定义和使用、EntityManager的配置和使用、JPA Query的使用等方面的内容。 1. 发展中的持久化技术 在Java应用程序中,持久化技术是一种非常重要的技术。 ...

    ejb实体bean实例

    3. **查询语言(JPA QL)**:除了基本的CRUD操作,还可以使用JPA的查询语言(JPQL)执行更复杂的SQL查询,如`SELECT e FROM EntityBean e WHERE e.property = :value`。 ### 四、EJB实体Bean的生命周期管理 EJB...

    Java-Persistence-API-开发文档.doc

    Java Persistence API开发文档 Java Persistence API(JPA)是一种Java应用程序接口,用于访问、...它涵盖了JPA的体系架构、Entity Bean、EntityManager、Persistence Unit等关键概念,并提供了实践指南和示例代码。

    spring-jpa

    Entity Bean 是 JPA 中的核心概念之一,它表示应用程序的数据模型。在 JPA 中,可以通过以下方式定义 Entity Bean: - 使用 `@Entity` 注解标记 Java 类,使其成为实体类。 - 定义实体类的属性,这些属性通常对应于...

    jpa相关资料jpa相关资料

    3. **Entity Bean** - **属性访问**:Entity类中的字段对应数据库表的列,可以通过注解来控制字段的访问方式,例如`@Column`、`@Id`等。 - **主键和实体标识**:每个实体都有一个唯一标识,通常用`@Id`注解指定...

    EJB3.0开发Entity.rar

    Entity Bean有两种类型:Bean-managed Persistence (BMP) 和 Container-managed Persistence (CMP)。EJB 3.0主要采用CMP,因为它自动处理了大部分的持久化工作,减少了代码量和复杂性。 **1. Entity Beans的标注** ...

Global site tag (gtag.js) - Google Analytics