오늘부터 다시 강의를 듣고 개인 과제를 완성하는 주차가 시작되었다. 새로운 강의가 주어져서 열심히 들어보려고 했는데 프로젝트 때 진행했던 것과 이전 과제들을 복습하느라 진도를 많이 나가지 못했다. 새로운 진도를 나가는 것보다 알고있는 것과 정리가 아직 덜 된 것들을 정리하는 것이 더 필요한 것 같아서 오늘은 시간을 그렇게 보냈던 것 같다. 내일은 진도를 쭉쭉 나갈 수 있을 것 같다.
여기에는 JPA의 @MappedSupperClass에 대해 알아본 것을 간단히 정리해보았다.
1. JPA의 @MappedSupperClass
JPA에는 @MappedSupperClass라는 것이 있다. 우리가 엔티티를 설계할 때 다수의 엔티티들에 공통적으로 들어있는 속성이 있을 수 있다. 이런 속성들을 하나로 묶어서 베이스 엔티티로 만들고 나서 상속받으면 상속받은 클래스에서도 칼럼으로 인식된다.
주로 생성시간, 수정시간 같이 거의 모든 엔티티에 공통적으로 들어가는 것들을 베이스 엔티티에 넣어두고 상속받아 사용한다. 이렇게 하면 같은 칼럼을 여러번 작성할 필요가 없어진다.
그렇지만 @MappedSupperClass는 단순히 엔티티가 공통적으로 사용하는 칼럼을 모아 편리하게 해주는 역할 그 이상 그 이하도 아니라는 점도 기억해야 한다.
@MappedSupperClass는 직접 생성해서 사용할 일이 없는 클래스이므로 보통 추상 클래스로 정의한다.
@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
abstract class BaseEntity {
// 생성 시간
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
var createdAt: LocalDateTime = LocalDateTime.now()
// 최종 수정 시간
@LastModifiedDate
@Column(name = "updated_at", nullable = false)
var updatedAt: LocalDateTime = LocalDateTime.now()
}
사용법은 너무나도 간단한데 아래와 같이 BaseEntity를 상속받기만 하면 된다. 그러면 자동으로 BaseEntity의 두 칼럼이 상속받은 클래스의 칼럼으로 인식된다.
Comment와 Todo 이렇게 두 엔티티에서 BaseEntity를 상속받아 보았다.
@Entity
@Table(name = "comment")
class Comment(
@Column
val writer: String,
@Column
var comment: String,
@Column
val password: String,
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "todo_id")
var todo: Todo
): BaseEntity() {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null
}
@Entity (name = "todo")
class Todo (
@Column
var title: String,
@Column
var writer: String,
@Column
var description: String,
@Column (name = "is_completed")
var isCompleted: Boolean = false
): BaseEntity() {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null
}
그런 다음 테이블을 생성해 잘 작동하는지 확인해보았다.
아래와 같이 정상적으로 칼럼으로 인식되며, 값도 잘 들어가는 것을 볼 수 있다.
만약 부모클래스의 칼럼명을 변경시키고 싶다면 @AttributeOverride를 사용하면 된다.
아래와 같이 (name = "부모 클래스의 변수명", column = Column(name = "바꾸고 싶은 칼럼명"))을 넣어주면 된다.
@AttributeOverride(name = "createdAt", column = Column(name = "created_time"))
@Entity (name = "todo")
class Todo (
@Column
var title: String,
@Column
var writer: String,
@Column
var description: String,
@Column (name = "is_completed")
var isCompleted: Boolean = false
): BaseEntity() {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null
}
위와 같이 하면 created_at을 created_time으로 변경할 수 있다. 그런데 쓸 일이 많을지는 모르겠다.
공부하다보니 자연스레 여태까지 id 값도 거의 매번 똑같이 GenerationType.IDENTITY로 DB에 생성을 맡겼었는데 이것도 @MappedSupperClass에 넣어도 괜찮지않을까 라는 생각이 들었다. 하지만 id값의 경우는 어플리케이션 규모가 커지면 여러가지 변경될 수 있는 여지가 많기 때문에(복합키를 사용하는 경우, id 값의 타입이 변경되어야하는 경우 등) 괜히 넣었다가 수정하는 것이 더 힘들 수도 있기 때문에 넣지 않는 것이 맞는 것 같다.
공부하다보니 스프링에는 편리하고 다양한 기능들이 참 많다는 것을 알게되었다. 편하다고 생각없이 사용하지 말고 잘 알고 사용하도록 공부해보아야겠다.
2. 오늘 배운 것
- 여태까지 배웠던 스프링 전체 과정에 대해 꼼꼼히 복습해보았다.
- @MappedSupperClass에 대해 정리해보았다.
'오늘 배운 것' 카테고리의 다른 글
24-06-06 Spring 설정 값 주입하기 (0) | 2024.06.06 |
---|---|
24-06-05 알고리즘 문제 풀이 (0) | 2024.06.05 |
24-06-03 팀 프로젝트 회고 (0) | 2024.06.03 |
24-06-02 정규 표현식 작성하기 (0) | 2024.06.02 |
24-06-01 Spring 팀 프로젝트 (5) (0) | 2024.06.01 |