(三)JPA – EntityManager的使用
- 2022 年 9 月 25 日
- 筆記
- JAVA, SpringData
建議在需要使用時,看看之前的文章,先把環境搭起來。
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)
不存在,則會拋出異常: