πŸ’‘ κ²Œμ‹œνŒ - JPA Auditiong으둜 μž‘μ„± μ‹œκ°„ μΆ”κ°€

박상민·2023λ…„ 9μ›” 4일
0

보톡 EntityλŠ” ν•΄λ‹Ή λ°μ΄ν„°μ˜ μƒμ„±μ‹œκ°„κ³Ό μˆ˜μ •μ‹œκ°„μ„ ν¬ν•¨ν•œλ‹€. μ΄λŸ¬ν•œ 생성/μˆ˜μ • μ •λ³΄λŠ” 후에 μœ μ§€λ³΄μˆ˜μ— μžˆμ–΄μ„œ ꡉμž₯히 μ€‘μš”ν•œ 정보이기 λ•Œλ¬Έμ— 항상 데이터와 ν•¨κ»˜ μ €μž₯ν•΄μ£ΌλŠ”κ²Œ μ’‹λ‹€. ν•˜μ§€λ§Œ 이λ₯Ό 맀번 DB에 μ‚½μž…ν• λ•Œ λ‚ μ§œ 데이터λ₯Ό 등둝/μˆ˜μ •ν•˜λŠ” μ½”λ“œλ₯Ό λ§Œλ“€μ–΄ μ£ΌλŠ” 것은 μ½”λ“œλ„ λ„ˆλ¬΄ μ§€μ €λΆ„ν•˜κ³ , λ„ˆλ¬΄ λ§Žμ€ 노동λ ₯이 λ“€μ–΄κ°€λŠ” 일일 것이닀. κ·Έλž˜μ„œ μ΄λŸ¬ν•œ 문제λ₯Ό ν•΄κ²°ν•˜κ³ μž JPA Auditing을 μ‚¬μš©ν•΄μ„œ 이λ₯Ό μžλ™ν™” ν•΄λ³΄μž.


μš°μ„  board ν…Œμ΄λΈ”μ— μž‘μ„± μ‹œκ°„μ— ν•΄λ‹Ήν•˜λŠ” created_date와 μˆ˜μ • μ‹œκ°„μ— ν•΄λ‹Ήν•˜λŠ” modified_dateλ₯Ό μΆ”κ°€ν•œλ‹€.

그리고 데이터에 λ‚ μ§œλ₯Ό μΆ”κ°€ν•΄μ£ΌκΈ° μœ„ν•΄μ„œ TimeEntityλ₯Ό λ§Œλ“€μ–΄μ£Όμž

TimeEntity.java

package com.studyweb.webboard.entity;

import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

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

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime modifiedDate;
}

@MappedSuperClass

  • JPA Entity ν΄λž˜μŠ€λ“€μ΄ TimeEntityλ₯Ό 상속할 경우 이 클래슀의 λ³€μˆ˜μΈ createdDate와 modifiedDate도 Column으둜 μΈμ‹ν•˜κ²Œν•œλ‹€.

@EntityListners(AuditingEntityListener.class)

  • TimeEntity ν΄λž˜μŠ€μ— Auditing κΈ°λŠ₯을 ν¬ν•¨μ‹œν‚¨λ‹€.

@CreatedDate

  • Entityκ°€ μƒμ„±λ˜λ©΄, createdDate에 μ €μž₯ μ‹œκ°„μ΄ μžλ™μœΌλ‘œ μ €μž₯λœλ‹€.

@LastModifiedDate

  • μ‘°νšŒν•œ Entity의 값을 λ³€κ²½ν•  λ•Œ μ‹œκ°„μ΄ μžλ™ μ €μž₯λœλ‹€.

package com.studyweb.webboard.entity;

import lombok.Data;
import lombok.Getter;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDateTime;

@Entity
@Data
public class Board extends TimeEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String title;
    private String content;
    private String author;

    //μˆ˜μ •μ„ μœ„ν•œ μƒμ„±μž
    public Board(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

    //κΈ°λ³Έ μƒμ„±μž μΆ”κ°€!
    public Board() {

    }
}

μ΄λ ‡κ²Œ λ§Œλ“€μ–΄μ€€ TimeEntityλ₯Ό Entity인 Board에 상속해쀀닀.

@SpringBootApplication
@EnableJpaAuditing
public class WebboardApplication {

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

}

그리고 JPA Auditing을 ν™œμ„±ν™”ν•  수 μžˆλ„λ‘ Application ν΄λž˜μŠ€μ— ν™œμ„±ν™” μ–΄λ…Έν…Œμ΄μ…˜μ„ μΆ”κ°€ν•΄μ£Όλ©΄, μžλ™μœΌλ‘œ λ°μ΄ν„°λ² μ΄μŠ€μ— μƒμ„±μ‹œκ°„κ³Ό μˆ˜μ •μ‹œκ°„μ„ ν¬ν•¨ν•˜μ—¬ μ €μž₯ν•  수 μžˆλ‹€.


μ§€κΈˆκΉŒμ§€ κΈ°λŠ₯을 μΆ”κ°€ν–ˆμœΌλ‹ˆ, μ‹€μ œλ‘œ 적용이 λ˜λŠ”μ§€ μž‘μ„±μ„ ν•΄λ³΄μž.


잘 적용이 λλŠ”μ§€ 확인 ν•˜κΈ° μœ„ν•΄ μœ„ 사진과 같이 κ²Œμ‹œκΈ€μ„ μž‘μ„±μ„ ν•΄μ€€λ‹€. 잘 적용이 λ˜μ—ˆλ‹€λ©΄ κ²Œμ‹œκΈ€μ΄ μž‘μ„±μ΄ λ˜λ©΄μ„œ DB에 μž‘μ„±μ‹œκ°„μ΄ μ €μž₯λ˜μ–΄ μžˆμ„ 것이닀.

DB 확인

DBλ₯Ό ν™•μΈν•΄λ³΄λ‹ˆ μž‘μ„±μ‹œκ°„μ΄ 잘 μ €μž₯된 것을 μ•Œ 수 μžˆλ‹€.

μˆ˜μ • μ‹œκ°„ 확인을 μœ„ν•œ κ²Œμ‹œκΈ€ μž‘μ„±

이제 μˆ˜μ • μ‹œκ°„λ„ 적용이 λλŠ”μ§€ 확인을 ν•΄μ•Όν•œλ‹€. λ”°λΌμ„œ, μœ„μ²˜λŸΌ κ²Œμ‹œκΈ€μ„ μˆ˜μ •ν•˜κ² λ‹€.

DB 확인

DBλ₯Ό ν™•μΈν•΄λ³΄λ‹ˆ μž‘μ„±μ‹œκ°„κ³Ό μˆ˜μ • μ‹œκ°„ λͺ¨λ‘ μ €μž₯λ˜μ–΄μžˆλŠ” 것을 λ³Ό 수 μžˆλ‹€.


μž‘μ„± μ‹œκ°„κ³Ό μˆ˜μ • μ‹œκ°„μ„ κ²Œμ‹œκΈ€μ—μ„œ ν™•μΈν•˜λ„λ‘ μˆ˜μ •

<!--μž‘μ„± μ‹œκ°„κ³Ό μˆ˜μ • μ‹œκ°„μ„ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•œ htmlμ½”λ“œ-->
<span th:if="${post.getCreatedDate() == post.getModifiedDate()}">
     <span th:text="'μž‘μ„± μ‹œκ°„: ' + ${#temporals.format(post.getCreatedDate(), 'yyyy.MM.dd HH:mm:ss')}"></span>
</span>

<span th:if="${post.getCreatedDate() != post.getModifiedDate()}">
     <span th:text="'μž‘μ„± μ‹œκ°„: ' + ${#temporals.format(post.getCreatedDate(), 'yyyy.MM.dd HH:mm:ss')}"></span><br>
     <span th:text="'μˆ˜μ • μ‹œκ°„: ' + ${#temporals.format(post.getModifiedDate(), 'yyyy.MM.dd HH:mm:ss')}"></span>
</span>

이제 κ²Œμ‹œκΈ€μ— μž‘μ„± μ‹œκ°„κ³Ό μˆ˜μ • μ‹œκ°„μ„ λ‚˜νƒ€λ‚΄μ£ΌλŠ” html을 μΆ”κ°€ν•΄μ„œ κ²Œμ‹œκΈ€ 상세 νŽ˜μ΄μ§€μ—μ„œ 확인을 ν•  수 μžˆλ„λ‘ ν•˜μ˜€λ‹€.


λ‹€μŒ 글은 νŽ˜μ΄μ§• μ²˜λ¦¬μ— λŒ€ν•΄μ„œ μž‘μ„±ν•˜κ² μŠ΅λ‹ˆλ‹€. κΈ€μ—μ„œ λΆ€μ‘±ν•œ 뢀뢄이 λ§Žμ„ 것 κ°™μŠ΅λ‹ˆλ‹€. λͺ¨λ“  지적을 ν™˜μ˜ν•©λ‹ˆλ‹€!!

더 μžμ„Έν•œ μ½”λ“œλŠ” κΉƒν—ˆλΈŒλ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”!

κΉƒν—ˆλΈŒ: https://github.com/pp8817/ToyProjectBoard

profile
μŠ€ν”„λ§ λ°±μ—”λ“œλ₯Ό 곡뢀쀑인 λŒ€ν•™μƒμž…λ‹ˆλ‹€!

0개의 λŒ“κΈ€