(二)JPA 连接工厂、主键生成策略、DDL自动更新

建议在需要使用时,看看之前的文章,先把环境搭起来。

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的使用的更多相关文章

  1. JPA EntityManager详解(一)

    JPA EntityManager详解(一) 持久化上下文(Persistence Contexts)的相关知识,内容包括如何从Java EE容器中创建EntityManager对象.如何从Java ...

  2. JPA EntityManager详解

    EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的java对象和数据库的数据存储.其接口如下: public interface EntityManager ...

  3. 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 ...

  4. spring data JPA entityManager查询 并将查询到的值转为实体对象

    spring data JPA entityManager查询 并将查询到的值转为实体对象 . https://blog.csdn.net/qq_34791233/article/details/81 ...

  5. [springboot jpa] [bug] Could not open JPA EntityManager for transaction

    前言 最近,测试环境遇到了一个问题.经过一番百度加谷歌,终于解决了这个问题.写下这篇博客是为了记录下解决过程,以便以后查看.也希望可以帮助更多的人. 环境 java版本:8 框架:spring clo ...

  6. 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 ...

  7. JPA EntityManager 在没有实体类的情况下返回Map

    JPA entityManager.createNativeQuery()执行原生的SQL,当我们查询结果没有对应的实体类时,query.getResultList()返回的是一个List<Ob ...

  8. springboot jpa 批量保存数据--EntityManager和 JpaRepository

    1: 项目里面使用springboo-boot-start-data-jpa操作数据库,通过源码,在repository上继承JpaRepository 可以实现保存操作,其中源码接口为: <S ...

  9. JPA基础

    目录 目录 1 一.JPA基础 2 1.1 JPA基础 2 1.2JPA开发过程 3 1.3 实体的生命周期及实体管理器常用方法 4 二.环境搭建 5 2.1 添加JPA支持 6 2.2 添加配置文件 ...

随机推荐

  1. 要想不踩SaaS那些坑,得先了解“SaaS架构”

    摘要:围绕当下许多企业青睐的SaaS应用开发,华为云开发者技术服务工程师程泽在DTT首期带来主题为 <SaaS云原生应用典型架构> 的DTT首期直播分享. 本文分享自华为云社区<DT ...

  2. 【万字长文】使用 LSM-Tree 思想基于.Net 6.0 C# 实现 KV 数据库(案例版)

    文章有点长,耐心看完应该可以懂实际原理到底是啥子. 这是一个KV数据库的C#实现,目前用.NET 6.0实现的,目前算是属于雏形,骨架都已经完备,毕竟刚完工不到一星期. 当然,这个其实也算是NoSQL ...

  3. 第十三天python3 生成器yield

    生成器generator 生成器指的是生成器对象,可由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象: 生成器函数 函数体中包含yield语句的函数,返 ...

  4. DQL分组查询和DQL分页查询

    分组查询: 1.语法:group by 分组字段: 2.注意: 分组之后查询的字符按:分组字段.聚合函数 where 和having 的区别 where再分组前进行限定,如果不满足条件则不参与分组.h ...

  5. AI全流程开发难题破解之钥

    摘要:通过对ModelArts.盘古大模型.ModelBox产品技术的解读,帮助开发者更好的了解AI开发生产线. 本文分享自华为云社区<[大厂内参]第16期:华为云AI开发生产线,破解AI全流程 ...

  6. 兔起鹘落全端涵盖,Go lang1.18入门精炼教程,由白丁入鸿儒,全平台(Sublime 4)Go lang开发环境搭建EP00

    Go lang,为并发而生的静态语言,源于C语言又不拘泥于性能,高效却不流于古板,Python灵活,略输性能,Java严谨,稍逊风骚.君不见各大厂牌均纷纷使用Go lang对自己的高并发业务进行重构, ...

  7. C 语言 时间函数使用技巧(汇总)

    time.h 头文件 是 C 语言中 有关 时间的函数所储存的头文件 #include <time.h> 在介绍时间函数用法之前,我们首先要了解在 time.h 头文件中已经声明了的一个结 ...

  8. layui框架图片上传至服务器

    注意:只可用于数据量较小的项目,数据量庞大的项目不要用这个,否则会造成图片数量庞大,至服务器运行速度变慢或瘫痪 HTML代码 //前端使用的是layui框架<div class="la ...

  9. DS队列----银行单队列多窗口模拟

    题目描述 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 本 ...

  10. Jira使用浅谈篇一

    本篇参考: https://www.jianshu.com/u/9dd427d9ad94 Salesforce 生命周期管理(二)Agile & Scrum 浅谈 我们都知道 salesfor ...