• EJB>持久化实体管理器EntityManager


    EntityManager 是用来对实体Bean 进行操作的辅助类。EntityManager 的获取可以通过@PersistenceContext 注释由EJB 容器动态注入,
    1、 Entity 获取find()或getReference()
    如果知道Entity 的唯一标示符,我们可以用find()或getReference()方法来获得Entity。
    @PersistenceContext
    protected EntityManager em;
    …
    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()方法不保证实体Bean 已被初始化。如果传递进getReference()或find()方法的参数不是实体Bean,都会引发IllegalArgumentException 例外。
    2、添加persist()
    Person person = new Person();
    person.setName(name);
    //把数据保存进数据库中
    em.persist(person);

    3更新实体

    当实体正在被容器管理时,你可以调用实体的set 方法对数据进行修改,在容器决定flush 时,更新的数据才会同
    步到数据库。如果你希望修改后的数据实时同步到数据库,你可以执行EntityManager.flush()方法。
    public void updatePerson() {
    try {
    Person person = em.find(Person.class, 1);
    person.setName("lihuoming"); //方法执行完后即可更新数据
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    4 合并Merge()
    merge ()方法是在实体Bean 已经脱离了EntityManager 的管理时使用,当容器决定flush 时,数据将会同步到数据库中。
    public boolean updatePerson(Person person) {
    try {
    em.merge(person);
    } catch (Exception e) {
    e.printStackTrace();
    return false;
    }
    return true;
    }
    执行em.merge(person)方法时,容器的工作规则:
    1.如果此时容器中已经存在一个受容器管理的具有相同ID 的person 实例,容器将会把参数person 的内容拷贝
    进这个受管理的实例,merge()方法返回受管理的实例,但参数person 仍然是分离的不受管理的。容器在决定Flush
    时把实例同步到数据库中。
    2.容器中不存在具有相同ID 的person 实例。容器根据传进的person 参数Copy 出一个受容器管理的person 实
    例,同时merge()方法会返回出这个受管理的实例,但参数person 仍然是分离的不受管理的。容器在决定Flush
    时把实例同步到数据库中。
    5 删除Remove()
    Person person = em.find(Person.class, 2);
    //如果级联关系cascade=CascadeType.ALL,在删除person 时候,也会把级联对象删除。把cascade属性设为cascade=CascadeType.REMOVE 有同样的效果。
    em.remove (person);

    6 执行JPQL操作createQuery()

    除了使用find()或getReference()方法来获得Entity Bean 之外,你还可以通过JPQL 得到实体Bean。要执行JPQL
    语句,你必须通过EntityManager 的createQuery()或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(); //影响的记录数
    7 执行SQL 操作createNativeQuery()
    注意这里操作的是SQL 语句,并非JPQL
    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();
    8 刷新实体refresh()
    如果你怀疑当前被管理的实体已经不是数据库中最新的数据,你可以通过refresh()方法刷新实体,容器会把数据库中的新值重写进实体。这种情况一般发生在你获取了实体之后,有人更新了数据库中的记录,这时你需要得到最新的数据。当然你再次调用find()或getReference()方法也可以得到最新数据,但这种做法并不优雅。
    protected EntityManager em
    Person person = em.find(Person.class, 2);
    //如果此时person 对应的记录在数据库中已经发生了改变,可以通过refresh()方法得到最新数据。
    em.refresh (person);
    9 检测实体当前是否被管理中contains()
    contains()方法使用一个实体作为参数,如果这个实体对象当前正被持久化内容管理,返回值为true,否则为false。
    Person person = em.find(Person.class, 2);
    if (em.contains(person)){
    //正在被持久化内容管理
    }else{
    //已经不受持久化内容管理
    }
    10 分离所有当前正在被管理的实体clear()
    在处理大量实体的时候,如果你不把已经处理过的实体从EntityManager 中分离出来,将会消耗你大量的内存。调用EntityManager 的clear()方法后,所有正在被管理的实体将会从持久化内容中分离出来。
    有一点需要说明下,在事务没有提交前(事务默认在调用堆栈的最后提交,如:方法的返回),如果调用clear()方法,之前对实体所作的任何改变将会掉失,所以建议你在调用clear()方法之前先调用flush()方法保存更改
    11 将实体的改变立刻刷新到数据库中flush()
    当实体管理器对象在一个session bean 中使用时,它是和服务器的事务上下文绑定的。实体管理器在服务器的事务提交时提交并且同步它的内容。在一个session bean 中,服务器的事务默认地会在调用堆栈的最后提交(如:方法的返回)。
    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();
    }
    }
    12、 改变实体管理器的Flush 模式setFlushMode()
    我们对Flush 模式进行修改需要使用到javax.persistence.FlushModeType,他的定义如下:
    public enum FlushModeType {
    AUTO,
    COMMIT
    }
    默认情况下,实体管理器的Flush 模式为AUTO,你可以改变他的值,如下:
    entityManager.setFlushMode(FlushModeType.COMMIT);
    下面说说这两者的区别及使用场合:
    FlushModeType.AUTO: 刷新在查询语句执行前(除了find()和getreference()查询)或事务提交时才发生,使用场合:在大量更新数据的过程中没有任何查询语句(除了find()和getreference()查询)的执行。
    FlushModeType.COMMIT:刷新只有在事务提交时才发生,使用场合:在大量更新数据的过程中存在查询语句(除了find()和getreference()查询)的执行。
    其实上面两种模式最终反映的结果是:JDBC 驱动跟数据库交互的次数。JDBC 性能最大的增进是减少JDBC 驱动与数据库之间的网络通讯。FlushModeType.COMMIT 模式使更新只在一次的网络交互中完成,而FlushModeType.AUTO 模式可能需要多次交互(触发了多少次Flush 就产生了多少次网络交互)。
     
  • 相关阅读:
    无线路由器的工作模式
    php 利用root 权限执行shell脚本
    shell 终端常用插件
    linux space/mark设置
    推送唯一标识符
    微信支付跨平台软件架构
    celery 动态配置定时任务
    两个报文是如何进行 TCP 分组传输
    接口 Interfaces
    How does Circus stack compare to a classical stack?
  • 原文地址:https://www.cnblogs.com/xqzt/p/5637378.html
Copyright © 2020-2023  润新知