美文网首页
JPA学习笔记三 EntityManager相关

JPA学习笔记三 EntityManager相关

作者: 殷俊杰 | 来源:发表于2018-03-14 20:46 被阅读0次

    Persistence

    主要用来创建EntityManagerFactory

    String persistenceUnitName = "jpa"; 
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenceUnitName);
    

    还有一个重载方法

    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("hibernate.format_sql", false);
    EntityManagerFactory factory= Persistence.createEntityManagerFactory(persistenceUnitName,properties);
    

    EntityManagerFactory

    EntityManagerFactory 接口主要用来创建 EntityManager 实例。该接口约定了如下4个方法:

    1. createEntityManager():用于创建实体管理器对象实例。

    2. createEntityManager(Map map):用于创建实体管理器对象实例的重载方法,Map 参数用于提供 EntityManager 的属性。

    3. isOpen():检查 EntityManagerFactory 是否处于打开状态。实体管理器工厂创建后一直处于打开状态,除非调用close()方法将其关闭。

    4. close():关闭 EntityManagerFactory 。 EntityManagerFactory 关闭后将释放所有资源,isOpen()方法测试将返回 false,其它方法将不能调用,否则将导致IllegalStateException异常。

    EntityManager

    以下代码省略了entityManager,entityManagerFactory,transaction的创建,关闭等过程

    find方法

    User user1=entityManager.find(User.class,1);//查出User实体类对应表中ID为1的对象
    System.out.println("-----------------华丽的分割线----------------");
    System.out.print(user1.getName());
    

    返回的是一个持久化对象,且立即查询


    image.png

    getReference方法

    User user1=entityManager.getReference(User.class,1);
    System.out.println("-----------------华丽的分割线----------------");
    System.out.print(user1.getName());
    
    image.png

    find方法在find的时候立即向数据库查询发起了sql语句查询,但是getReference方法是在真正使用对象的时候才会向数据库查询,于是find的时候就输出了sql语句然后输出分割线,getReference时因为没有使用user对象,在输出分割线后再输出user对象时才使用到user对象此时才向数据库查询并输出sql语句。

    persist方法

           User user=new User();
            user.setName("殷俊杰");
            user.setEmail("247385709@qq.com");
            entityManager.persist(user);
            transaction.commit();
            System.out.println(user.getId());
    
    image.png

    当我们保存的时候并没有设置ID值,但是输出的时候却又ID,这是由主键生成策略自动生成并设置到对象属性中去的。
    和hibernate的save方法类似,但又有所不同,如果对象有ID,则不能进行insert操作,否则会报错,如下

            User user=new User();
            user.setName("殷俊杰");
            user.setEmail("247385709@qq.com");
            user.setId(3);
            entityManager.persist(user);
            transaction.commit();
            System.out.println(user.getId());
    

    报错


    image.png

    remove方法

    remove方法只能移除持久化对象,没什么说的,只能删除数据库中有的对象。
    下面这段代码会报错,因为是我们自己创建的对象

    Order order = new Order();
    order.setId(140);
    entityManager.remove(order);
    

    必须是从数据库中查出来的对象才能删除

    Order order = new Order();
    order = entityManager.find(Order.class, 140);
    entityManager.remove(order);
    

    merge方法

    情况一,传入对象没有ID

            User user=new User();
            user.setName("殷俊杰");
            user.setEmail("247385709@qq.com");
            entityManager.merge(user);
            transaction.commit();
            System.out.println(user.getId());
    
    image.png

    向数据库中插入了一条新数据,但是并不会把ID值自动设置到对象属性中去


    image.png

    情况二,传入兑现更有ID值,但是EntityManager中无缓存,数据库中也没有对应ID的对象

    目前的数据库


    image.png
           User user=new User();
            user.setName("奔波儿灞");
            user.setEmail("247385709@qq.com");
            user.setId(100);
            entityManager.merge(user);
    
    image.png

    这个ID是假的。。
    插入后的数据库


    image.png

    情况三,传入对象有ID,EntityManager的缓存中没有,数据库中有

           User user=new User();
            user.setName("奔波儿灞");
            user.setEmail("哈哈哈哈");
            user.setId(5);
            entityManager.merge(user);
    

    看起来是更新了对吧


    image.png

    就是更新了没错


    image.png

    情况四,传入对象有ID,EntityManager和数据库中均有该对象

    emm,和三一样,更新,没的说

    flush方法

    Order order= entityManager.find(Order.class, 170);
    System.out.println("order:"+order);
    order.setOrderName("bbb");
    //5. 提交事务
    transaction.commit();
    
    image.png
    order是通过find方法查出来的是持久化对象,虽然没merge但是commit时,缓存会被更新到数据库。
    而flush方法,可以强制将缓存更新到数据库
    entityManager.flush();
    与之相关:
    • setFlushMode (FlushModeType flushMode):设置持久上下文环境的Flush模式。参数可以取2个枚举
    • FlushModeType.AUTO 为自动更新数据库实体,
    • FlushModeType.COMMIT 为直到提交事务时才更新数据库记录。
    • getFlushMode ():获取持久上下文环境的Flush模式。返回FlushModeType类的枚举值。

    refresh方法、

    Order order= entityManager.find(Order.class, 170);
    order= entityManager.find(Order.class, 170);
    

    运行以上代码,发现调用了两次find,但是只执行了一次select语句,这是缓存导致的。


    image.png

    再看下面的方法

    rder order= entityManager.find(Order.class, 170);
    entityManager.refresh(order);
    

    只调用了一次find方法,却执行了两次select语句,这是因为refresh方法会去查看缓存中的数据状态和数据库中是否一致,因此又执行了一次select语句


    image.png

    clear ()

    清除持久上下文环境,断开所有关联的实体。如果这时还有未提交的更新则会被撤消。

    contains (Object entity):

    判断一个实例是否属于当前持久上下文环境管理的实体。

    isOpen ()

    判断当前的实体管理器是否是打开状态。

    getTransaction ()

    返回资源层的事务对象。EntityTransaction实例可以用于开始和提交多个事务。

    close ()

    关闭实体管理器。之后若调用实体管理器实例的方法或其派生的查询对象的方法都将抛出 IllegalstateException 异常,除了getTransaction 和 isOpen方法(返回 false)。不过,当与实体管理器关联的事务处于活动状态时,调用 close 方法后持久上下文将仍处于被管理状态,直到事务完成。

    createQuery (String qlString)

    创建一个查询对象。

    createNamedQuery (String name)

    根据命名的查询语句块创建查询对象。参数为命名的查询语句。

    createNativeQuery (String sqlString)

    使用标准 SQL语句创建查询对象。参数为标准SQL语句字符串。

    createNativeQuery (String sqls, String resultSetMapping)

    使用标准SQL语句创建查询对象,并指定返回结果集 Map的 名称。

    。。。。。。。。。撤撤撤
    参考文章
    http://blog.csdn.net/u010837612/article/category/5732811

    相关文章

      网友评论

          本文标题:JPA学习笔记三 EntityManager相关

          本文链接:https://www.haomeiwen.com/subject/nadqqftx.html