(三)JPA - EntityManager的使用
建议在需要使用时,看看之前的文章,先把环境搭起来。
4、EntityManager
EntityManager 是完成持久化操作的核心对象。
EntityManager 对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。
上面测试代码中,已经使用过EntityManager完成持久化操作。
实体类的状态:
新建状态: 新创建的对象,尚未拥有持久性主键;
持久化状态:已经拥有持久性主键并和持久化建立了上下文环境;
游离状态:拥有持久化主键,但是没有与持久化建立上下文环境;
删除状态: 拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除。
4.1 persist 增
persist (Object entity):用于将新创建的 Entity 纳入到 EntityManager 的管理。该方法执行后,传入 persist() 方法的 Entity 对象转换成持久化状态。如果传入 persist() 方法的 Entity 对象已经处于持久化状态,则 persist() 方法什么都不做。
如果对删除状态的 Entity 进行 persist() 操作,会转换为持久化状态。
如果对游离状态的实体执行 persist() 操作,可能会在 persist() 方法抛出 EntityExistException(也有可能是在flush或事务提交后抛出)。
测试代码:
@Test
public void testPersist() {
// 获取连接
EntityManager entityManager = JPAEntityFactory.getEntityManager();
// 开启事务
entityManager.getTransaction().begin();
// 新建状态实例
Course course = new Course();
course.setCname("Spring编程实战");
course.setStart(DateUtil.stringToDate("2022-09-19"));
course.setEnd(DateUtil.stringToDate("2022-12-30"));
course.setCredit(2);
course.setNum(88);
// 对新建状态 持久化
entityManager.persist(course);
// 提交事务
entityManager.getTransaction().commit();
// 关闭连接
JPAEntityFactory.close();
}
// 日志信息
insert into course (cname, credit, end, num, start) values (?, ?, ?, ?, ?)
如果设置了id,就说明这是一个游离状态的实体类,执行会出现异常
4.2 merge 增\改
merge() 用于处理 Entity的同步。即数据库的插入和更新操作。

测试代码: 传入新建状态的对象
@Test
public void testMerge() {
// 获取连接
EntityManager entityManager = JPAEntityFactory.getEntityManager();
// 开启事务
entityManager.getTransaction().begin();
Course course = new Course();
course.setCname("Spring编程实战");
course.setStart(DateUtil.stringToDate("2022-09-19"));
course.setEnd(DateUtil.stringToDate("2022-12-30"));
course.setCredit(2);
course.setNum(88);
// 对新建状态 持久化
entityManager.merge(course);
// 提交事务
entityManager.getTransaction().commit();
// 关闭连接
JPAEntityFactory.close();
}
查看日志,可以看到,执行的是插入操作。
insert into course (cname, credit, end, num, start) values (?, ?, ?, ?, ?)
测试代码: 传入游离状态对象
@Test
public void testMerge() {
// 获取连接
EntityManager entityManager = JPAEntityFactory.getEntityManager();
// 开启事务
entityManager.getTransaction().begin();
Course course = new Course();
course.setCid(2L);
course.setCname("Spring编程实战");
course.setStart(DateUtil.stringToDate("2022-09-19"));
course.setEnd(DateUtil.stringToDate("2022-12-30"));
course.setCredit(2);
course.setNum(88);
// 对新建状态 持久化
entityManager.merge(course);
// 提交事务
entityManager.getTransaction().commit();
// 关闭连接
JPAEntityFactory.close();
}
查看日志,可以看到,执行的是Update语句
update course set cname=?,credit=?,end=?, num=?, start=? where cid=?
4.3 remove 删
删除实例。如果实例是被管理的,即与数据库实体记录关联,则同时会删除关联的数据库记录。
注意:该方法只能移除持久化对象。
@Test
public void testRemove() {
// 获取连接
EntityManager entityManager = JPAEntityFactory.getEntityManager();
// 开启事务
entityManager.getTransaction().begin();
// 查询
Course course = entityManager.find(Course.class, 2);
// 对新建状态 持久化
entityManager.remove(course);
// 提交事务
entityManager.getTransaction().commit();
// 关闭连接
JPAEntityFactory.close();
}
查看日志,可以看到,执行的是Delete语句
delete from course where cid=?
4.4 find 查
find (Class<T> entityClass,Object primaryKey):返回指定的 OID 对应的实体类对象。第一个参数为被查询的实体类类型,第二个参数为待查找实体的主键值。
如果这个实体存在于当前的持久化环境,则返回一个被缓存的对象;否则会创建一个新的 Entity, 并加载数据库中相关信息;若 OID 不存在于数据库中,则返回一个 null。
@Test
public void testFind() {
// 获取连接
EntityManager entityManager = JPAEntityFactory.getEntityManager();
// 开启事务
entityManager.getTransaction().begin();
// 查询主键为3L
Course course = entityManager.find(Course.class, 3L);
loggerFactory.info("【find查询结果:】{}", course);
// 提交事务
entityManager.getTransaction().commit();
// 关闭连接
JPAEntityFactory.close();
}
查看日志信息:【find查询结果:】Course(cid=3, cname=Spring编程实战, start=2022-09-19, end=2022-12-30, credit=2, num=88)
4.5 getReference 查
getReference (Class<T> entityClass,Object primaryKey):与find()方法类似。不同的是:如果缓存中不存在指定的 Entity, EntityManager 会创建一个 Entity 类的代理,但是不会立即加载数据库中的信息,只有第一次真正使用此 Entity 的属性才加载,所以如果此 OID(主键) 在数据库不存在,getReference() 不会返回 null 值, 而是抛出EntityNotFoundException。
@Test
public void testGetReference() {
// 获取连接
EntityManager entityManager = JPAEntityFactory.getEntityManager();
// 开启事务
entityManager.getTransaction().begin();
Course course = entityManager.getReference(Course.class, 3L);
loggerFactory.info("【find查询结果:】{}", course);
// 提交事务
entityManager.getTransaction().commit();
// 关闭连接
JPAEntityFactory.close();
}
查看日志信息:【find查询结果:】Course(cid=3, cname=Spring编程实战, start=2022-09-19, end=2022-12-30, credit=2, num=88)
不存在,则会抛出异常:

(三)JPA - EntityManager的使用的更多相关文章
- JPA EntityManager详解(一)
JPA EntityManager详解(一) 持久化上下文(Persistence Contexts)的相关知识,内容包括如何从Java EE容器中创建EntityManager对象.如何从Java ...
- JPA EntityManager详解
EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的java对象和数据库的数据存储.其接口如下: public interface EntityManager ...
- Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Cannot open connection
Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceE ...
- spring data JPA entityManager查询 并将查询到的值转为实体对象
spring data JPA entityManager查询 并将查询到的值转为实体对象 . https://blog.csdn.net/qq_34791233/article/details/81 ...
- [springboot jpa] [bug] Could not open JPA EntityManager for transaction
前言 最近,测试环境遇到了一个问题.经过一番百度加谷歌,终于解决了这个问题.写下这篇博客是为了记录下解决过程,以便以后查看.也希望可以帮助更多的人. 环境 java版本:8 框架:spring clo ...
- spring boot配置spring-data-jpa的时候报错CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.NoSuchMethodError
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager f ...
- JPA EntityManager 在没有实体类的情况下返回Map
JPA entityManager.createNativeQuery()执行原生的SQL,当我们查询结果没有对应的实体类时,query.getResultList()返回的是一个List<Ob ...
- springboot jpa 批量保存数据--EntityManager和 JpaRepository
1: 项目里面使用springboo-boot-start-data-jpa操作数据库,通过源码,在repository上继承JpaRepository 可以实现保存操作,其中源码接口为: <S ...
- JPA基础
目录 目录 1 一.JPA基础 2 1.1 JPA基础 2 1.2JPA开发过程 3 1.3 实体的生命周期及实体管理器常用方法 4 二.环境搭建 5 2.1 添加JPA支持 6 2.2 添加配置文件 ...
随机推荐
- Redis三种模式——主从复制,哨兵模式,集群
一.Redis主从复制作用 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复:实际上是一种服务的冗余. 负 ...
- CF222C Reducing Fractions
题目大意: 给出两个集合,第一个集合数的乘积是分子,第二个集合的数的乘积是分母,要求够造一个同样的集合,但是得到的分数是最简分数. 分析: 寻找思路并不复杂,对两个集合的每个数进行质因数分解,然后统计 ...
- MD5,Des,RSA加密解密
一.加密和解密 下面先熟悉几个概念 1>对称加密:加密的key和解密的key是同一个 但是如何确保密钥安全地进行传递?秘钥的安全是一个问题 2>非对称加密:加密点的key和解密的key不是 ...
- 多线程与高并发(三)—— 源码解析 AQS 原理
一.前言 AQS 是一个同步框架,关于同步在操作系统(一)-- 进程同步 中对进程同步做了些概念性的介绍,我们了解到进程(线程同理,本文基于 JVM 讲解,故下文只称线程)同步的工具有很多:Mutex ...
- WindTerm:新一代开源免费的终端工具,GitHub星标6.6k+,太酷了!
继 Tabby.Warp 后,今天再来给大家推荐一款终端神器--WindTerm,完全开源,在 GitHub 上已经收获 6.6k 的 star. https://github.com/kingToo ...
- selenium webDriver的运用
声明实例运行浏览器 配置浏览器驱动后,可以通过简单的2行代码就可以驱动浏览器(配置这里不加赘述) from selenium import webdriver driver = webdriver.C ...
- codeforces600E Lomsat gelral【线段树合并/DSU】
第一次AC这道题,是三年前的一个下午,也许晚上也说不定.当时使用的\(DSU\) \(on\) \(tree\)算法,如今已经淡忘,再学习新的算法过程中,却与旧物重逢.生活中充满不可知会的相遇,即使重 ...
- Spring 05: 用DI(依赖注入)优化Spring接管下的三层项目架构
背景 用注解改造前面Spring博客集里(指 Spring 02)Spring接管下的三层项目架构 对前面Spring博客集里(指 Spring 04)@Controller + @Service + ...
- kafka手动设置offset
项目中经常有需求不是消费kafka队列全部的数据,取区间数据 查询kafka最大的offset: ./kafka-run-class.sh kafka.tools.GetOffsetShell --b ...
- MySQL事务概念与流程和索引控制
MySQL事务概念与流程和索引控制 视图 1.什么是视图 我们在执行SQL语句其实就是对表进行操作,所得到的其实也是一张表,而我们需要经常对这些表进行操作,拼接什么的都会产生一张虚拟表,我们可以基于该 ...