Spring Boot에서 감사

감사란?



감사는 데이터와 관련된 트랜잭션을 추적하고 기록하는 것을 의미하며, 단순히 삽입, 업데이트 및 삭제 작업(사용자 및/또는 작업 날짜)을 기록하는 것을 의미합니다.

Spring에서 @Entity의 생성/업데이트 날짜를 추가하는 방법은 무엇입니까?



이는 다양한 접근 방식을 사용하여 달성할 수 있습니다.
  • 데이터베이스 내장 솔루션: Oracle Database 12c, Db2, MySQL Enterprise Audit...
  • 데이터베이스 트리거 생성,
  • 타사 도구 사용
  • 업데이트 열을 생성하고 각 엔티티에 대해 생성하고 모든 변경 사항을 데이터베이스에 수동으로 기록합니다(완전히 직접 작성),
  • 스프링 감사 사용 💡

  • 이 마지막 선택은 추적 논리를 추가하기 위해 엔터티 비즈니스 논리를 건드릴 필요가 없으며 변경 사항을 기록하기 위해 엔터티에 열을 추가하거나 테이블을 추가할 필요가 없습니다.

    Spring을 사용하는 경우 엔터티를 추적하는 헤드리스 솔루션입니다. 한 번 구성하고 모든 곳에서 사용합니다.

    Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and the point in time this happened. (spring)



    구현



    가능한 접근법:

    1. 표준 JPA를 사용한 구현:
    엔터티의 테이블 자체를 사용하여 변경 사항을 기록합니다. 이 경우 삭제 작업을 감사할 수 없습니다.
    2. Hibernate가 제공하는 감사 기능을 사용하여 구현:
    엔터티의 테이블이 아닌 다른 테이블에 로그인하여 삭제 작업을 기록할 수 있습니다.
    3. Spring Data JPA💡에서 제공하는 감사 기능을 사용하여 구현:
    Spring Security와 통합할 준비가 된 속성 감사를 위한 편리한 주석을 제공하며 JPA 접근 방식의 동일한 결함을 상속하므로 삭제 작업을 기록하는 데 사용할 수도 없습니다.

    다음으로 Spring Data JPA로 감사 구현을 다룰 것입니다.

    📝 체크포인트/할 일:
  • AuditorAware 및 Spring Security를 ​​사용하는 감사 작성자(@CreatedBy@LastModifiedBy 추가 허용).
  • @EnableJpaAuditing을 사용하여 JPA 감사 활성화
  • Spring 데이터 주석 @CreatedDate@LastModifiedDate을 사용하여 일반 감사 가능 클래스를 만듭니다.
  • 감사 가능한 클래스의 확장을 추적하려는 엔티티에 추가하십시오.

  • 1- 감사를 구성하는 데 사용할 AuditorAware 구현을 만듭니다.

    import org.springframework.data.domain.AuditorAware;
    import java.util.Optional;
    
    public class AuditorAwareImpl implements AuditorAware<String> {
    
            // Returning empty instead of user since we're tracking just dates not users
        @Override
        public Optional<String> getCurrentAuditor() {
            return Optional.empty();
        }
    
            // Use the following to get the actual connected user
            /*
        public User getCurrentAuditor() {
    
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    
            if (authentication == null || !authentication.isAuthenticated()) {
                return null;
            }
    
            return ((MyUserDetails) authentication.getPrincipal()).getUser();
        }
        */
    }
    


    2- 이 구성 클래스를 스프링 부트 프로젝트의 구성 디렉토리에 추가하여 감사를 활성화합니다.

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.domain.AuditorAware;
    import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
    
    @Configuration
    @EnableJpaAuditing(auditorAwareRef = "auditorProvider")
    public class JpaAuditingConfig {
        @Bean
        AuditorAware<String> auditorProvider() {
            return new AuditorAwareImpl();
        }
    }
    


    3- 감사가 활성화되면 Auditable 클래스를 생성하여 원하는 곳(모델 클래스에서) 어디에서나 확장할 수 있습니다.

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.data.annotation.CreatedDate;
    import org.springframework.data.annotation.LastModifiedDate;
    import org.springframework.data.jpa.domain.support.AuditingEntityListener;
    
    import javax.persistence.Column;
    import javax.persistence.EntityListeners;
    import javax.persistence.MappedSuperclass;
    import java.util.Date;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @MappedSuperclass
    @EntityListeners(AuditingEntityListener.class)
    public class Auditable<U>
    {
        @CreatedDate
        @Column(name = "created_date")
        protected Date createdDate;
    
        @LastModifiedDate
        @Column(name = "last_modified_date")
        protected Date lastModifiedDate;
    
        // To track the user that modified or created use @LastModifiedBy and @CreatedBy
    
        //@LastModifiedBy
        //protected U lastModifiedBy;
    
        //@CreatedBy
        //protected U createdBy;
    
    }
    


    4- 마지막으로 Auditable 클래스에서 확장하여 변경 사항을 추적합니다. 예:

    @Data
    @Entity
    @NoArgsConstructor
    @Table(name = "products")
    public class Product extends Auditable<String> {
        @Id
        @Column(name = "id")
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;
    }
    


    created_datelast_modified_date은 데이터베이스의 products 테이블에 자동으로 추가되며, Product 클래스는 Auditable 클래스를 확장하므로 createdDatelastModifiedDate 속성은 Product 의 다른 속성과 동일한 방식으로 사용할 수 있습니다.

    추가 정보:
    Official docs

    좋은 웹페이지 즐겨찾기