☞ 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
:回滚事务
/**
* 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();
}
}
@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();
}
@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);
}
@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();
}
@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();
}
@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 中的缓存清除,可以看到执行了两次查询操作,对象的地址值也不同。
JPQL 全称 Java Persistence Query Language,JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。其特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。JPQL 语言的语句可以是 select 语句、update 语句或 delete 语句,它们都通过 Query 接口封装执行。Query 接口封装了执行数据库查询的相关方法。调用 EntityManager 的 createQuery、createNamedQuery 及 createNativeQuery 方法可以获得查询对象,进而可调用 Query 接口的相关方法来执行查询操作。
方法 | 描述 |
---|---|
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 异常 |
☞ 查询全部
@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();
}