Spring Data JPA使用@EntityListener
攔截entity存取資料庫操作範例。
在entity類別名稱前掛上JPA的@EntityListener
可指定攔截操作的處理器類別。
範例環境:
- Java 8
- Spring Boot 2.3.2.RELEASE
- Spring Data JPA
- H2 database
- JUnit 5
例如下面在Employee
entity類加上@EntityListener
,指定EntityLogListener
負責對此entity的資料庫操作進行攔截。
Employee
package com.abc.demo.entity;
import com.abc.demo.entity.listener.EntityLogListener;
import javax.persistence.*;
import java.io.Serializable;
@EntityListeners(EntityLogListener.class)
@Entity
public class Employee implements Serializable {
private static final Long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
private Integer age;
// constructors, getters, setters, hashCode(), equals(), toString()
}
Repository類EmployeeRepository
提供對Employee
的持久操作方法。
EmployeeRepository
package com.abc.demo.repository;
import com.abc.demo.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
下面為自訂的攔截處理器EntityLogListener
,搭配JPA callback annotation在CRUD操作的前後插入印出log的邏輯。
EntityLogListener
package com.abc.demo.entity.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.*;
public class EntityLogListener {
Logger log = LoggerFactory.getLogger(EntityLogListener.class);
/** 查詢後 */
@PostLoad
private void logPostLoad(Object entity) {
log.info("retrieved entity={}", entity);
}
/** 新增前 */
@PrePersist
private void logPrePersist(Object entity) {
log.info("pre-insert entity={}", entity);
}
/** 新增後 */
@PostPersist
private void logPostPersist(Object entity) {
log.info("post-insert entity={}", entity);
}
/** 更新前 */
@PreUpdate
private void logPreUpdate(Object entity) {
log.info("pre-udpate entity={}", entity);
}
/** 更新後 */
@PostUpdate
private void logPostUpdate(Object entity) {
log.info("post-update entity={}", entity);
}
/** 刪除前 */
@PreRemove
private void logPreRemove(Object entity) {
log.info("pre-delete entity={}", entity);
}
/** 刪除後 */
@PostRemove
private void logPostRemove(Object entity) {
log.info("post-delete entity={}", entity);
}
}
測試
在EmployeeRepositoryTests
測試類中對Employee
執行CRUD操作觀察是否有插入log。
EmployeeRepositoryTests
package com.abc.demo.repository;
import com.abc.demo.entity.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class EmployeeRepositoryTests {
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void test() {
// insert
Employee employee = new Employee(4, "Jack", 26);
employee = employeeRepository.save(employee);
// update
employee.setName("Jackson");
employeeRepository.save(employee);
// delete
employeeRepository.delete(employee);
}
}
執行可看到console中確實在CRUD前後印出EntityLogListener
插入的log。
2021-06-23 14:45:06.660 DEBUG 9188 --- [ main] o.h.SQL : select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.name as name3_0_0_ from employee employee0_ where employee0_.id=?
2021-06-23 14:45:06.664 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [1] as [BIGINT] - [4]
2021-06-23 14:45:06.671 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : pre-insert entity=Employee(id=4, name=Jack, age=26)
2021-06-23 14:45:06.679 DEBUG 9188 --- [ main] o.h.SQL : insert into employee (id, age, name) values (null, ?, ?)
2021-06-23 14:45:06.681 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [1] as [INTEGER] - [26]
2021-06-23 14:45:06.681 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [2] as [VARCHAR] - [Jack]
2021-06-23 14:45:06.685 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : post-insert entity=Employee(id=1, name=Jack, age=26)
2021-06-23 14:45:06.692 DEBUG 9188 --- [ main] o.h.SQL : select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.name as name3_0_0_ from employee employee0_ where employee0_.id=?
2021-06-23 14:45:06.693 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2021-06-23 14:45:06.696 TRACE 9188 --- [ main] o.h.t.d.s.BasicExtractor : extracted value ([age2_0_0_] : [INTEGER]) - [26]
2021-06-23 14:45:06.696 TRACE 9188 --- [ main] o.h.t.d.s.BasicExtractor : extracted value ([name3_0_0_] : [VARCHAR]) - [Jack]
2021-06-23 14:45:06.697 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : retrieved entity=Employee(id=1, name=Jack, age=26)
2021-06-23 14:45:06.698 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : pre-udpate entity=Employee(id=1, name=Jackson, age=26)
2021-06-23 14:45:06.701 DEBUG 9188 --- [ main] o.h.SQL : update employee set age=?, name=? where id=?
2021-06-23 14:45:06.702 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [1] as [INTEGER] - [26]
2021-06-23 14:45:06.702 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [2] as [VARCHAR] - [Jackson]
2021-06-23 14:45:06.702 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [3] as [BIGINT] - [1]
2021-06-23 14:45:06.704 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : post-update entity=Employee(id=1, name=Jackson, age=26)
2021-06-23 14:45:06.705 DEBUG 9188 --- [ main] o.h.SQL : select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.name as name3_0_0_ from employee employee0_ where employee0_.id=?
2021-06-23 14:45:06.706 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2021-06-23 14:45:06.708 TRACE 9188 --- [ main] o.h.t.d.s.BasicExtractor : extracted value ([age2_0_0_] : [INTEGER]) - [26]
2021-06-23 14:45:06.708 TRACE 9188 --- [ main] o.h.t.d.s.BasicExtractor : extracted value ([name3_0_0_] : [VARCHAR]) - [Jackson]
2021-06-23 14:45:06.709 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : retrieved entity=Employee(id=1, name=Jackson, age=26)
2021-06-23 14:45:06.710 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : pre-delete entity=Employee(id=1, name=Jackson, age=26)
2021-06-23 14:45:06.715 DEBUG 9188 --- [ main] o.h.SQL : delete from employee where id=?
2021-06-23 14:45:06.716 TRACE 9188 --- [ main] o.h.t.d.s.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2021-06-23 14:45:06.717 INFO 9188 --- [ main] c.a.d.e.l.EntityLogListener : post-delete entity=Employee(id=1, name=Jackson, age=26)
沒有留言:
張貼留言