SpringDateJPA 系列之 JPA 中的相关操作
1.1 JPA 的使用
1.1.1 JPA 中的 API
☞ Persistence 对象
Persistence 对象主要作用是用于获取 EntityManagerFactory 对象的 。通过调用该类的 createEntityManagerFactory 静态方法,根据配置文件中持久化单元名称创建 EntityManagerFactory。
EntityManagerFactory factory= Persistence.createEntityManagerFactory(name);
☞ EntityManagerFactory
由于 EntityManagerFactory 是一个线程安全的对象(即多个线程访问同一个 EntityManagerFactory 对象不会有线程安全问题),并且 EntityManagerFactory 的创建极其浪费资源,所以在使用 JPA 编程时,我们可以对 EntityManagerFactory 的创建进行优化,只需要做到一个工程只存在一个EntityManagerFactory 即可。
☞ EntityManager
在 JPA 规范中,EntityManager 是完成持久化操作的核心对象。实体类作为普通 java 对象,只有在调用 EntityManager 将其持久化后才会变成持久化对象。EntityManager 对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过 JPQL 语句查询实体。我们可以通过调用 EntityManager 的方法完成获取事务,以及持久化数据库的操作。
♞ getTransaction
:获取事务对象
♞ persist
:保存操作
♞ merge
: 更新操作
♞ remove
: 删除操作
♞ find/getReference
: 根据 id 查询
☞ EntityTransaction
在 JPA 规范中, EntityTransaction 是完成事务操作的核心对象,对于 EntityTransaction 在我们的 java 代码中承接的功能比较简单。
♞ begin
:开启事务
♞ commit
:提交事务
♞ rollback
:回滚事务
1.1.2 抽取 JPAUtil 工具类
/**
* Created with IntelliJ IDEA.
*
* @author Demo_Null
* @date 2020/7/29
* @description JPA 工具类
*/
public class JPAUtil {
// JPA 的实体管理器工厂:相当于 Hibernate的SessionFactory
private static EntityManagerFactory em;
static {
// 注意:该方法参数必须和 persistence.xml 中 persistence-unit 标签 name 属性取值一致
em = Persistence.createEntityManagerFactory("myJpa");
}
/**
* 使用管理器工厂生产一个管理器对象
* @author Demo_Null
* @date 2020/7/29
* @param
* @return javax.persistence.EntityManager
**/
public static EntityManager getEntityManager() {
return em.createEntityManager();
}
}
1.2 JPA 的 CRUD
1.2.1 新增
@Test
public void add() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 准备数据
Student student = new Student();
student.setName("张三");
student.setAge(23);
student.setSex(false);
// 新增
entityManager.persist(student);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
1.2.2 修改
@Test
public void update() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 根据 id 查询
Student student = entityManager.find(Student.class, 1L);
System.out.println(student);
student.setName("李大嘴");
// 将 student 缓存清除
entityManager.clear();
// 修改
Student merge = entityManager.merge(student);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
System.out.println(merge);
}
1.2.3 删除
@Test
public void delete() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 根据 id 查询
Student student = entityManager.find(Student.class, 1L);
// 删除
entityManager.remove(student);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
1.2.4 查询
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 根据 id 查询
Student student = entityManager.getReference(Student.class, 1L);
System.out.println(student);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
1.2.5 缓存
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 根据 id 查询
Student student1 = entityManager.getReference(Student.class, 2L);
System.out.println(student1);
Student student2 = entityManager.getReference(Student.class, 2L);
System.out.println(student2);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
我们从打印结果可以看出,两次查询所得的对象地址值是一样的,说明第二次查询使用了缓存,并没有重新去数据库中查询。而且日志也明确可以看出只执行了一次查询操作。如果我们再两次查询中间使用 clear() 方法将 EntityManager 中的缓存清除,可以看到执行了两次查询操作,对象的地址值也不同。
1.3 JPQL
1.3.1 概述
JPQL 全称 Java Persistence Query Language,JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。其特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。JPQL 语言的语句可以是 select 语句、update 语句或 delete 语句,它们都通过 Query 接口封装执行。Query 接口封装了执行数据库查询的相关方法。调用 EntityManager 的 createQuery、createNamedQuery 及 createNativeQuery 方法可以获得查询对象,进而可调用 Query 接口的相关方法来执行查询操作。
1.3.2 常用方法
方法 |
描述 |
---|---|
int executeUpdate() |
用于执行 update 或 delete 语句 |
List getResultList() |
用于执行 select 语句并返回结果集实体列表 |
Object getSingleResult() |
用于执行只返回单个结果实体的 select 语句 |
Query setFirstResult(int startPosition) |
用于设置从哪个实体记录开始返回查询结果 |
Query setMaxResults(int maxResult) |
用于设置返回结果实体的最大数。与 setFirstResult 结合使用可实现分页查询 |
Query setFlushMode(FlushModeType flushMode) |
设置查询对象的 Flush 模式。参数可以取2个枚举值:FlushModeType.AUTO 为自动更新数据库记录FlushMode Type.COMMIT 为直到提交事务时才更新数据库记录 |
setHint(String hintName, Object value) |
设置与查询对象相关的特定供应商参数或提示信息参数名及其取值需要参考特定 JPA 实现库提供商的文档如果第二个参数无效将抛出 IllegalArgumentException 异常 |
setParameter(int position, Object value) |
为查询语句的指定位置参数赋值。Position 指定参数序号,value 为赋给参数的值 |
setParameter(int position, Date d, TemporalType type) |
为查询语句的指定位置参数赋 Date 值Position 指定参数序号value 为赋给参数的值temporalType 取 TemporalType 的枚举常量,包括 DATE、TIME 及 TIMESTAMP |
setParameter(int position, Calendar c, TemporalType type) |
为查询语句的指定位置参数赋 Calendar 值position 指定参数序号value 为赋给参数的值temporalType 的含义及取舍同前 |
setParameter(String name, Object value) |
为查询语句的指定名称参数赋值 |
setParameter(String name, Date d, TemporalType type) |
为查询语句的指定名称参数赋 Date 值,用法同前 |
setParameter(String name, Calendar c, TemporalType type) |
为查询语句的指定名称参数设置Calendar值name为参数名,其它同前该方法调用时如果参数位置或参数名不正确,或者所赋的参数值类型不匹配,将抛出 IllegalArgumentException 异常 |
1.3.3 示例
☞ 查询全部
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// from Student(类名,不是表名) 为省略写法,写全为 select stu from Student as stu,不能使用 select *
// 查询某些字段使用 select stu.id from Student as stu 或者 select id from Student
String jpql = "from Student";
// 创建 Query 对象
Query query = entityManager.createQuery(jpql);
// 获取查询结果
List resultList = query.getResultList();
System.out.println(resultList);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
☞ 分页查询
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 创建 Query 对象
String jpql = "select stu from Student as stu";
Query query = entityManager.createQuery(jpql);
// 分页 从第 0 条开始查,查询 2 条
query.setFirstResult(0);
query.setMaxResults(2);
// 获取查询结果
List resultList = query.getResultList();
System.out.println(resultList);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
☞ 条件查询
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 创建 Query 对象
String jpql = "from Student where age < ? ";
Query query = entityManager.createQuery(jpql);
// 给第一个 ? 赋值
query.setParameter(1,24);
// 获取查询结果
List resultList = query.getResultList();
System.out.println(resultList);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
☞ 排序
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 创建 Query 对象
String jpql = "from Student order by id desc";
Query query = entityManager.createQuery(jpql);
// 获取查询结果
List resultList = query.getResultList();
System.out.println(resultList);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
☞ 聚合函数
@Test
public void query() {
// 获取 EntityManager 对象
EntityManager entityManager = JPAUtil.getEntityManager();
// 获取 EntityTransaction 对象
EntityTransaction transaction = entityManager.getTransaction();
// 开始事务
transaction.begin();
// 创建 Query 对象
String jpql = "select count(id) from Student";
Query query = entityManager.createQuery(jpql);
// 获取查询结果
Object singleResult = query.getSingleResult();
System.out.println(singleResult);
// 提交事务
transaction.commit();
// 释放资源
entityManager.close();
}
- 其实添加数据也可以这样简单——表单的第三步抽象(针对UI及后置代码)
- 为Symfony2和Redis正名,基于PHP的10亿请求/周网站打造
- 如何使用Python基线预测进行时间序列预测
- 如何使用统计显着性检验来解释机器学习结果
- 其实添加数据也可以这样简单——表单的第一步抽象(针对数据访问层)《怪怪设计论: 抽象无处不在 》有感
- WCF服务端运行时架构体系详解[上篇]
- 使命必达: 深入剖析WCF的可靠会话[编程篇](下)
- 在网页里让文本框只能输入数字的一种方法。外加回车换Tab
- 如何用Python从零开始实现简单的线性回归
- 使命必达: 深入剖析WCF的可靠会话[编程篇](上)
- 页面回发后,让页面自动滚动到指定位置的一种简单的方法
- [自定义服务器控件] 第二步:下拉列表框。
- WCF服务端运行时架构体系详解[中篇]
- [自定义服务器控件] 第三步:CheckBoxList。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 微服务[学成在线] day08:FastDFS 实现课程图片管理
- 【MySQL入门】之细说脏读、幻读及不可重复读
- 微服务[学成在线] day09:Eureka、Feign、课程预览实现
- 【MySQL入门】之MySQL数据库的锁机制(一)
- 【MySQL入门】之MySQL数据库的锁机制(二)
- 【MySQL】删库别着急跑路(一)--Xtrabackup的原理及使用
- 微服务[学成在线] day11:基于 ElasticSearch 构建搜索服务
- 【MySQL】删库别着急跑路(二)--mysqldump的使用
- 【MySQL】删库别着急跑路(三)--binlog2sql闪回工具的使用
- 微服务[学成在线] day10:课程发布、ElasticSearch
- MySql监控分析视图-sys schema
- 如何使用PyMysql操作MySQL数据库?
- 【redis】部署及参数详解(吐血整理,建议收藏)
- 【MySQL性能调优】-关于索引的那些事儿(一)
- 【索引潜规则】-覆盖索引、ICP、MRR详解