본문 바로가기
JPA

섹션 6. 확장기능

by 문자메일 2024. 9. 30.

 

사용자 정의 리포지토리 구현

  • 스프링 데이터 JPA 리포지토리는 인터페이스만 정의하고 구현체는 스프링이 자동 생성
  • 스프링 데이터 JPA가 제공하는 인터페이스를 직접 구현하면 구현해야 하는 기능이 너무 많다.
  • 다양한 이유로 인터페이스의 메서드를 직접 구현하고 싶다면?
    • JPA 직접 사용 ('EntityManager')
    • 스프링 JDBC Template 사용
    • MyBatis 사용
    • 데이터베이스 커넥션 직접 사용 등등..
    • Querydsl 사용

 

커스텀 인터페이스 생성

 

커스텀 인터페이스 구현체 생성

 

기존 리포지토리에 커스텀 인터페이스 상속

아래처럼 쓰면 spring data jpa가 구현체 알아서 찾아서 묶어준다고 한다. (단 구현 클래스 네이밍 규칙 등 맞춰야 함)

 

 

 

번외로 JpaRepository 같은 것 상속 없이 리포지토리 따로 만들어서 기능 구현해서 사용하는 경우도 있다고 한다. 

 

 

 

Auditing

엔티티를 생성 변경할 때 변경한 사람과 시간을 추적하고 싶으면?

  • 등록일
  • 수정일
  • 등록자
  • 수정자

 

기본 JPA  버전

@Getter
@MappedSuperclass
public class JpaBaseEntity {

    @Column(updatable = false)
    private LocalDateTime createdDate;
    private LocalDateTime updatedDate;

    @PrePersist
    public void prePersist(){
        LocalDateTime now = LocalDateTime.now();
        createdDate = now;
        updatedDate = now;
    }

    @PreUpdate
    public void preUpdate(){
        updatedDate = LocalDateTime.now();
    }
}

 

 

스프링 Data JPA 버전

@EntityListeners(AuditingEntityListener.class)
@Getter
@MappedSuperclass
public class BaseTimeEntity {

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
}

 

@EntityListeners(AuditingEntityListener.class)
@Getter
@MappedSuperclass
public class BaseEntity extends BaseTimeEntity{

    @CreatedBy
    @Column(updatable = false)
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;
}

 

Entity에서 BaseEntity 상속

@ToString(of = {"id", "username", "age"})
public class Member extends BaseEntity{

    @Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;

 

메인 설정 클래스에서 @EnableJpaAuditing 추가

@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {

   public static void main(String[] args) {
      SpringApplication.run(DataJpaApplication.class, args);
   }

 

아래는 테스트 결과

@Test
public void JpaEventBaseEntity() throws InterruptedException {
    // given
    Member member = new Member("member1");
    memberRepository.save(member); // @Prepersist

    Thread.sleep(100);
    member.setUsername("member2");

    em.flush(); // @PreUpdate
    em.clear();

    // when
    Member findMember = memberRepository.findById(member.getId()).get();

    // then
    System.out.println("findMember.createdDate = " + findMember.getCreatedDate());
    System.out.println("findMember.updatedDate = " + findMember.getLastModifiedDate());
    System.out.println("findMember.createdBy = " + findMember.getCreatedBy());
    System.out.println("findMember.updatedBy = " + findMember.getLastModifiedBy());
}

댓글