JPA学习笔记(5)——EntityManager相关
2015-08-14 18:53
381 查看
Persistence
EntityManagerFactory
EntityManager
find方法
getReference方法
persist方法
remove方法
merge方法
情况1传入的对象没有id
情况2传入的对象有identityManager的缓存中没有该对象数据库中没有该记录
情况3传入的对象有identityManager的缓存没有该对象数据库中有该记录
情况4传入的对象有identityManager的缓存有该对象
flush方法
refresh方法
clear
contains Object entity
isOpen
getTransaction
close
createQuery String qlString
createNamedQuery String name
createNativeQuery String sqlString
createNativeQuery String sqls String resultSetMapping
其实它还有一个重载方法可用
这里的properties,和配置文件persistence.xml中的属性是一样的。
createEntityManager():用于创建实体管理器对象实例。
createEntityManager(Map map):用于创建实体管理器对象实例的重载方法,Map 参数用于提供 EntityManager 的属性。
isOpen():检查 EntityManagerFactory 是否处于打开状态。实体管理器工厂创建后一直处于打开状态,除非调用close()方法将其关闭。
close():关闭 EntityManagerFactory 。 EntityManagerFactory 关闭后将释放所有资源,isOpen()方法测试将返回 false,其它方法将不能调用,否则将导致IllegalStateException异常。
这个方法的使用和find()一样,但是有一些区别,看下方运行结果截图:
在代码中,我先调用getReference,然后打印“- - - - - - ”,最后打印order对象
但是从截图看,是先打印“- - - - -”,然后才查询order,接着打印order。
原因:调用getReference()方法,返回的其实并不是order对象,而是一个代理。当你要使用order时,才会真正的调用查询语句来查询order对象
执行insert操作,相当于hibernate的save()方法
从上面代码中可以看到,我们并没有给order一个id,但是在执行persist方法之后,没有从数据库查询,order.getId()也可以获取到值。这也是persist方法的一个功能:使对象由临时状态变为持久化状态。
结果截图:
但是和hibernate的save()方法有些不同:如果对象有id,则不能执行insert操作,会抛出异常
remove()方法不能移除游离对象,只能移除持久化对象,什么意思呢?对比下面两段代码:
上面这段代码会抛出异常,因为order是我们自己创建的对象,也就是游离对象。
必须这样写:
这段代码中的order是从数据库中获取的,也就是持久化对象
hibernate的delete()方法,只要对象有Id,就可以删除
结论:在这种情况下,调用merge方法,将返回一个新的对象(有id),并对这个新的对象执行insert操作。
结论:在这种情况下,调用merge方法,将返回一个新的对象,并对该对象执行insert操作。新对象的id是数据库中这条记录的id(比如自增长的id),而不是我们自己传入的id。(其实和情况1的结果是一样的)
调用前数据库表:
调用后结果:
结论:在这种情况下,调用merge方法,将会从数据库中查询对应的记录,生成新的对象,然后将我们传入的对象复制到新的对象,最后执行update操作。 简单来说,就是更新操作
结果和情况3一样,就不截图了。
结论:在这种情况下,调用merge方法,JPA会把传入的对象赋值到entityManager的缓存中的对象,然后对entityManager缓存中的对象执行update操作。(和情况3的结果一样)
然后执行以下代码
查看结果:
结果发现,JPA居然执行了update操作,把aaa改成了bbb,但是在代码中我们并没有执行update操作啊。
原因:order是通过find方法查询出来的,因此它是持久化对象,也就是说它缓存在entityManager中,当事务提交时,缓存将会被更新到数据库。
而flush方法,可以强制将缓存更新到数据库
与之相关:
setFlushMode (FlushModeType flushMode):设置持久上下文环境的Flush模式。参数可以取2个枚举
FlushModeType.AUTO 为自动更新数据库实体,
FlushModeType.COMMIT 为直到提交事务时才更新数据库记录。
getFlushMode ():获取持久上下文环境的Flush模式。返回FlushModeType类的枚举值。
运行以上代码,发现调用了两次find,但是只执行了一次select语句,这是缓存导致的。
再看下面的代码:
只调用了一次find方法,却执行了两次select语句,这是因为refresh方法会去查看缓存中的数据状态和数据库中是否一致,因此又执行了一次select语句
EntityManagerFactory
EntityManager
find方法
getReference方法
persist方法
remove方法
merge方法
情况1传入的对象没有id
情况2传入的对象有identityManager的缓存中没有该对象数据库中没有该记录
情况3传入的对象有identityManager的缓存没有该对象数据库中有该记录
情况4传入的对象有identityManager的缓存有该对象
flush方法
refresh方法
clear
contains Object entity
isOpen
getTransaction
close
createQuery String qlString
createNamedQuery String name
createNativeQuery String sqlString
createNativeQuery String sqls String resultSetMapping
Persistence
在之前的JPA学习笔记(2)——创建JPA项目,有使用到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);
这里的properties,和配置文件persistence.xml中的属性是一样的。
EntityManagerFactory
EntityManagerFactory 接口主要用来创建 EntityManager 实例。该接口约定了如下4个方法:createEntityManager():用于创建实体管理器对象实例。
createEntityManager(Map map):用于创建实体管理器对象实例的重载方法,Map 参数用于提供 EntityManager 的属性。
isOpen():检查 EntityManagerFactory 是否处于打开状态。实体管理器工厂创建后一直处于打开状态,除非调用close()方法将其关闭。
close():关闭 EntityManagerFactory 。 EntityManagerFactory 关闭后将释放所有资源,isOpen()方法测试将返回 false,其它方法将不能调用,否则将导致IllegalStateException异常。
EntityManager
以下代码省略了entityManager,entityManagerFactory,transaction的创建,关闭等过程find方法
//查询ID为1的Order Order order = entityManager.find(Order.class, 1);
getReference方法
Order order = entityManager.getReference(Order.class, 1); System.out.println("-------------------------------------"); System.out.println(order);
这个方法的使用和find()一样,但是有一些区别,看下方运行结果截图:
在代码中,我先调用getReference,然后打印“- - - - - - ”,最后打印order对象
但是从截图看,是先打印“- - - - -”,然后才查询order,接着打印order。
原因:调用getReference()方法,返回的其实并不是order对象,而是一个代理。当你要使用order时,才会真正的调用查询语句来查询order对象
persist方法
Order order = new Order(); order.setOrderName("hehe"); entityManager.persist(order); System.out.println("id="+order.getId());
执行insert操作,相当于hibernate的save()方法
从上面代码中可以看到,我们并没有给order一个id,但是在执行persist方法之后,没有从数据库查询,order.getId()也可以获取到值。这也是persist方法的一个功能:使对象由临时状态变为持久化状态。
结果截图:
但是和hibernate的save()方法有些不同:如果对象有id,则不能执行insert操作,会抛出异常
remove方法
相当于hibernate的delete()方法,但是有些不同:remove()方法不能移除游离对象,只能移除持久化对象,什么意思呢?对比下面两段代码:
Order order = new Order(); order.setId(140); entityManager.remove(order);
上面这段代码会抛出异常,因为order是我们自己创建的对象,也就是游离对象。
必须这样写:
Order order = new Order(); order = entityManager.find(Order.class, 140); entityManager.remove(order);
这段代码中的order是从数据库中获取的,也就是持久化对象
hibernate的delete()方法,只要对象有Id,就可以删除
merge方法
情况1:传入的对象没有id
Order order = new Order(); order.setOrderName("hehe"); Order order2 = entityManager.merge(order); System.out.println("order2#id:"+order2.getId());
结论:在这种情况下,调用merge方法,将返回一个新的对象(有id),并对这个新的对象执行insert操作。
情况2:传入的对象有id,entityManager的缓存中没有该对象,数据库中没有该记录
Order order = new Order(); order.setId(1000); order.setOrderName("hehe"); Order order2 = entityManager.merge(order); System.out.println("order#id:"+order.getId()); System.out.println("order2#id:"+order2.getId());
结论:在这种情况下,调用merge方法,将返回一个新的对象,并对该对象执行insert操作。新对象的id是数据库中这条记录的id(比如自增长的id),而不是我们自己传入的id。(其实和情况1的结果是一样的)
情况3:传入的对象有id,entityManager的缓存没有该对象,数据库中有该记录
Order order = new Order(); order.setId(170); order.setOrderName("wahahahahah"); Order order2 = entityManager.merge(order); System.out.println("order:"+order); System.out.println("order2:"+order2);
调用前数据库表:
调用后结果:
结论:在这种情况下,调用merge方法,将会从数据库中查询对应的记录,生成新的对象,然后将我们传入的对象复制到新的对象,最后执行update操作。 简单来说,就是更新操作
情况4:传入的对象有id,entityManager的缓存有该对象
Order order = new Order(); order.setId(170); order.setOrderName("xixixixi"); //通过find来将对象读入entityManager缓存 Order order3 = entityManager.find(Order.class, 170); Order order2 = entityManager.merge(order); System.out.println("order:"+order); System.out.println("order2:"+order2);
结果和情况3一样,就不截图了。
结论:在这种情况下,调用merge方法,JPA会把传入的对象赋值到entityManager的缓存中的对象,然后对entityManager缓存中的对象执行update操作。(和情况3的结果一样)
flush方法
先查看数据库,有一条记录如下:然后执行以下代码
Order order= entityManager.find(Order.class, 170); System.out.println("order:"+order); order.setOrderName("bbb"); //5. 提交事务 transaction.commit();
查看结果:
结果发现,JPA居然执行了update操作,把aaa改成了bbb,但是在代码中我们并没有执行update操作啊。
原因:order是通过find方法查询出来的,因此它是持久化对象,也就是说它缓存在entityManager中,当事务提交时,缓存将会被更新到数据库。
而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语句,这是缓存导致的。
再看下面的代码:
Order order= entityManager.find(Order.class, 170); entityManager.refresh(order);
只调用了一次find方法,却执行了两次select语句,这是因为refresh方法会去查看缓存中的数据状态和数据库中是否一致,因此又执行了一次select语句
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的 名称。相关文章推荐
- 找到最大的迭代次数串
- ajax 提交序列化表单
- SPOJ NSUBSTR - Substrings
- Boostrap入门+样式学习--壹--
- 九度 Online Judge 算法 刷题 题目1057:众数
- 栈的应用--简单计算器---加减乘除
- ios Masonary的使用
- arcengine 文件夹连接
- 学习笔记-----Android的View绘制过程
- 杭电3342Legal or Not
- iOS arc与非arc混编 以及设置UINavigationBar的高度
- POJ 1061 青蛙的约会(扩展欧几里得算法)
- Java高级应用(一个)-文件夹监控服务
- HDU 3377 插头dp
- No package mysql-server available.
- Nginx模块开发(5)————开发简单的HTTP过滤模块
- MySQL5.6安装步骤(windows7/8_64位)
- Ubuntu下git使用
- APK 代码混淆
- poj2367