반응형
해당 글은 스프링 부트와 AWS로 혼자 구현하는 웹 서비스라는 책을 읽고 핵심 내용을 정리하기 위해 작성하는 글입니다.
03장 스프링 부트에서 JPA로 데이터베이스 다뤄보자
1️⃣ JPA 의존성 추가하기
JPA를 사용하기 위해 build.gradle에 의존성을 추가해야 한다.
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2'
- spring-boot-starter-data-jpa: 스프링 부트용 Spring Data Jpa 추상화 라이브러리
- h2: 인메모리 관계형 데이터베이스로 별도의 설치가 필요 없이 프로젝트 의존성만으로 관리할 수 있음.
2️⃣ JPA를 이용하여 Entity 클래스 설정하기
아래 Posts 클래스는 실제 DB의 테이블과 매칭될 클래스이며 , 보통 Entity 클래스라고 한다.
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Generated;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@Entity // ①
public class Posts {
@Id // ②
@GeneratedValue(strategy = GenerationType.IDENTITY) // ③
private Long id;
@Column(length = 500, nullable = false) // ④
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder // ⑤
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
}
JPA 제공 어노테이션
- ① @Entity: 테이블과 링크될 클래스임을 나타낸다. 클래스의 카멜케이스 이름을 언더스코어 네이밍(_)으로 테이블 이름을 매칭한다.
ex) SalesManager.java → sales_manager table - ② @Id: 해당 테이블의 PK 필드
📒 주민등록번호와 같이 비즈니스상 유니크 키나, 여러 키를 조합한 복합키를 PK로 설정하지 말자.
why? 여러 가지 문제가 발생할 수 있다.
1. 데이터베이스의 인덱스에는 제한이 있으며, 제한을 초과할 시 오류가 발생할 수 있다.
2. 여러 개의 칼럼으로 이루어진 복합키를 기반으로 검색하면, 검색 속도가 느려진다.
3. 주민등록번호와 같은 비즈니스상 유니크한 값을 PK로 설정하는 것은 보안상의 문제가 있을 수 있다. PK로 설정하면 해당 값이 노출될 가능성이 높아지며, 이는 보안 문제로 이루어질 수 있다.
→ 따라서 PK로는 Long 타입의 Auto_increment를 추천한다!
- ③ @GeneratedValue: PK의 생성 규칙. 스프링 부트 2.0에서는 GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 된다.
- ④ @Column: 테이블의 칼럼을 나타내며, 굳이 선언하지 않더라도 해당 클래스의 필드는 모두 칼럼이 된다. 기본값 외에 추가로 변경이 필요한 옵션이 있는 경우에 사용한다.
ex) VARCHAR(255) 기본값의 사이즈를 500으로 늘리고 싶은 경우
롬복 라이브러리의 어노테이션
- ⑤ @Builder: 해당 클래스의 빌더 패턴 클래스를 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함.
빌더 패턴이란❓
공부하면서 빌더 패턴이 무엇인지에 대해 궁금해졌고 추가로 조사해 보는 시간을 가졌다.
빌더 패턴은 복합 객체를 생성하는 방법 중 하나이다. 롬복 라이브러리를 통해 빌더 패턴을 쉽게 구현할 수 있다.
이 패턴은 생성자 인자로 너무 많은 인자가 전달될 때 유용하다.
빌더 패턴의 장점❗
- 빌더 패턴을 사용하면 객체를 생성할 때 인자의 순서나 개수에 구애받지 않고 원하는 값을 설정할 수 있다.
- 복잡한 객체를 생성할 때 코드를 간결하고 가독성을 높게 유지할 수 있다.
3️⃣ Repository(DB Layer 접근자) 생성
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostsRepository extends JpaRepository<Posts, Long> {
}
Repository는 인터페이스를 생성 후, JpaRepository<Entity 클래스, PK 타입>을 상속하면 기본적인 CRUD 메소드가 자동으로 생성된다.
이때 Entity 클래스와 기본 Entity Repository는 동일 디렉토리에 위치해야 한다.
4️⃣ Spring Web Layer
Web Layer
- 흔히 사용하는 컨트롤러(@Controller)와 JSP/Freemarker 등의 뷰 템플릿 영역
Service Layer
- @Service에 사용되는 서비스 영역
- 일반적으로 Controller와 Repository Layer의 중간 영역에서 사용
- @Transactional이 사용되어야 하는 영역
Repository Layer
- Database와 같이 데이터 저장소에 접근하는 영역
Dtos
- Dto는 계층 간에 데이터 교환을 위한 객체를 이야기하며 Dtos는 이들의 영역을 얘기함.
- ex) 뷰 템플릿 엔진에서 사용될 객체나 Repository Layer에서 결과로 넘겨준 객체 등
Domain Model
- 도메인이라 불리는 개발 대상을 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화시킨 것을 도메인 모델이라 함.
- @Entity가 사용된 영역
- 비즈니스 처리 담당
비즈니스 모델의 종류 및 차이 알아보기: https://da-y-0522.tistory.com/74
5️⃣ 영속성 컨텍스트
영속성 컨텍스트란?
- 엔티티를 영구 저장하는 환경이라는 뜻이다.
- 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 논리적 개념
- 트랜잭션 내부에서 데이터베이스의 데이터를 가져오면 해당 데이터는 영속성 컨텍스트가 유지된 상태이다.
이 상태에서 해당 데이터의 값을 변경하면 더티 체킹한다. (Entity 객체의 값만 변경하면 별도로 Update 쿼리를 날릴 필요가 없다.)
더티 체킹(dirty checking)
- 엔티티의 변경이 끝나면, 변경 내용을 자동으로 데이터베이스에 반영하는 JPA의 특징
- 더티 체킹을 진행하는 검사의 대상은 영속성 컨텍스트가 관리하는 엔티티를 대상으로 한다.
@Transactional
public Long update(Long id, PostsUpdateRequestDto requestDto) {
Posts posts = postsRepository.findById(id)
.orElseThrow(() -> new
IllegalArgumentException("해당 게시글이 없습니다. id=" + id));
posts.update(requestDto.getTitle(), requestDto.getContent());
return id;
}
위 코드에서 posts(Entity)의 내용을 변경하고, Update 쿼리를 따로 날리지 않아도 값이 변경된다.
6️⃣JPA Auditing
- Spring Date JPA에서는 Auditing 기능을 제공한다.
- 이를 사용하여 엔티티가 생성되고, 변경되는 시점을 감지하여 생성시각, 수정시각, 생성한 사람, 수정한 사람을 기록할 수 있다.
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
@CreatedDate
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime modifiedDate;
}
- @MappedSuperclass: JPA Entity 클래스들이 BaseTimeEntity를 상속할 경우 필드들도 칼럼으로 인식하도록 함
- @EntityListeners(AuditingEntityListener.class): BaseTimeEntity 클래스에 Auditing 기능을 포함
- @CreateDate: Entity가 생성되어 저장될 때 시간이 자동 저장
- @LastModifiedDate: 조회한 Entity의 값을 변경할 때 시간이 자동 저장
그 외에 @CreatedBy, @LastModifiedBy 어노테이션도 존재
@Getter
@NoArgsConstructor
@Entity
public class Posts extends BaseTimeEntity {
...생략
}
Entity에 BaseTimeEntity를 상속받도록 변경
@EnableJpaAuditing // JPA Auditing 활성화
@SpringBootApplication
public class InhaSpringStudyApplication {
public static void main(String[] args) {
SpringApplication.run(InhaSpringStudyApplication.class, args);
}
}
JPA Auditing 어노테이션을 활성화할 수 있도록 Application 클래스에 EnableJpaAuditing 어노테이션 추가
반응형
'Java > Spring' 카테고리의 다른 글
[Spring] 서블릿(servlet)에 대해 알아보자 (0) | 2023.04.05 |
---|---|
[Spring] 타임리프(Thymeleaf)에 대해 알아보자! (0) | 2023.04.01 |
[Spring] 비즈니스 로직을 처리하는 패턴 (0) | 2023.03.31 |
[Spring] Model 객체와 @ModelAttribute 어노테이션 (0) | 2023.03.25 |
[Spring] Spring vs Spring Boot (0) | 2023.03.22 |