이젠 본격적으로 JPA 환경설정을 수정해봅니다.
기존의 pom.xml에 jpa 및 postgresql 사용을 위한 다음의 dependency들을 추가 합니다.
pom.xml
<!-- JPA 의존성 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- PostgreSQL 의존성 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
application.yml
mvn clean install 명령어를 수행 후, application.yml에 다음 내용들을 추가합니다.
spring:
datasource:
url: jdbc:postgresql://localhost:5432/${dbName}
username: ***********
password: ***********
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: update # 테이블 자동 생성 및 업데이트
show-sql: true # 실행되는 SQL 쿼리 출력
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
여기서, ddl-auto에 대해 아래에서 좀 더 내용을 살펴보도록 하겠습니다.
ddl-auto 옵션
spring.jpa.hibernate.ddl-auto는 JPA에서 데이터베이스 스키마 관리를 제어하는 설정 옵션으로,
Hibernate가 데이터베이스 테이블을 어떻게 생성하고 업데이트할지를 결정합니다.
이 옵션에는 다양한 값이 있으며, 각 값은 특정한 동작을 수행합니다.
ddl-auto의 주요 옵션 종류
- none
- Hibernate가 데이터베이스 스키마에 대한 어떠한 작업도 수행하지 않습니다. 즉, 애플리케이션이 실행될 때 테이블을 생성하거나 수정하지 않으며, 사용자가 수동으로 스키마를 관리해야 합니다.
- validate
- 데이터베이스에 이미 존재하는 테이블과 JPA 엔티티 간의 매핑이 일치하는지 검증만 합니다. 데이터베이스를 변경하거나 수정하지 않으며, 매핑이 일치하지 않으면 애플리케이션이 실행되지 않습니다.
- update
- 데이터베이스에 없는 테이블이나 컬럼을 자동으로 추가하지만, 기존 데이터는 삭제하지 않습니다. 애플리케이션이 실행될 때마다 엔티티 클래스와 매핑된 대로 데이터베이스 구조를 업데이트합니다.
- create
- 애플리케이션이 실행될 때마다 데이터베이스의 기존 테이블을 삭제하고, 엔티티에 따라 새로 테이블을 생성합니다. 기존 데이터는 모두 사라지므로, 주의해서 사용해야 합니다.
- create-drop
- create와 동일하게 애플리케이션이 실행될 때 테이블을 생성하지만, 애플리케이션이 종료될 때 테이블을 삭제합니다. 테스트 환경에서 유용할 수 있습니다.
- create-only (Hibernate 6에서 도입)
- 애플리케이션이 실행될 때 데이터베이스 스키마를 처음 한 번 생성하고, 이후로는 유지합니다. 기존의 테이블을 변경하거나 업데이트하지 않고, 단지 생성만 합니다.
요약
- 테스트용: create, create-drop
- 개발용: update
- 운영/프로덕션 환경: validate, none (스키마는 수동 관리)
프로덕션 환경에서는 데이터 손실 위험이 있는 create, update는 피하고, validate나 none을 주로 사용해 수동으로 스키마를 관리하는 것이 권장됩니다.
우리는 테스트/개발용 이기에, create-drop 및 update 설정을 실행해보도록 하겠습니다.
1. create-drop으로 설정
- create와 동일하게 애플리케이션이 실행될 때 테이블을 생성하지만, 애플리케이션이 종료될 때 테이블을 삭제합니다. 테스트 환경에서 유용할 수 있습니다.
- 이 설정을 이용하여 test_users 테이블 생성 뒤, id, name, email 컬럼 생성 후 특정 값을 insert 해보도록 하겠습니다.
- 이 조건에 의하면, 서버 compile 시 test_users 테이블 생성 후 -> stop 시, test_users 테이블이 drop 됩니다.
application.yml
yml 파일에 있는 ddl-auto를 create-drop으로 변경해보도록 하겠습니다.
jpa:
hibernate:
#ddl-auto: update
ddl-auto: create-drop
User.java
Table name에 test_users를 지정하고 id, name, email 객체를 생성하고 getter & setter를 생성합니다.
이 때, id는 시퀀스 값처럼 자동으로 증가하는 값이기 때문에, 따로 설정하지 않아도 됩니다. (시작 넘버 : 1)
package com.example.my_rest_api.model;
import jakarta.persistence.*;
@Entity
@Table(name = "test_users")
public class User {
// primary key 설정을 하지 않으면 실행시 에러가 발생합니다.
@Id
// id 는 자동으로 1씩 증가됩니다. (start : 1)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
RestService.java
이제 User 객체를 가져와 데이터들을 등록합니다.
@Autowired
private UserRepository userRepository;
@PostConstruct
public void init() {
// 애플리케이션이 시작될 때 샘플 데이터 추가
User user = new User();
user.setName("Sarah");
user.setEmail("sarah@example.com");
userRepository.save(user);
System.out.println("User saved: " + user);
}
UserRepository.java
UserRepository 인터페이스를 지정해 JpaRepository 를 상속받습니다.
package com.example.my_rest_api.repository;
import com.example.my_rest_api.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
이 때, JpaRepository에서 User, Long을 파라미터로 넣는 이유는,
JpaRepository class가 다음 코드를 지니고 있기 때문입니다.
// T는 GenericType, ID는 아까 우리가 선정한 id 값이라고 볼 수 있습니다.
public interface JpaRepository<T, ID>
- DB 변경 내역 확인
서버를 중지하면, 다음과 같이 Table이 제거된 것을 확인할 수 있습니다.
RestService.java
이해를 돕기 위해, User에 1명을 더 추가해보도록 하겠습니다.
@PostConstruct
public void init() {
// 애플리케이션이 시작될 때 샘플 데이터 추가
User user = new User();
user.setName("Sarah");
user.setEmail("sarah@example.com");
userRepository.save(user);
// 한명 더 추가합니다.
User user2 = new User();
user2.setName("Tom");
user2.setEmail("tom@example.com");
userRepository.save(user);
System.out.println("User saved: " + user);
}
DB 변경 내역
확인해 보면, 이전의 데이터는 제거 되고, 2개의 row가 나오는 것을 확인할 수 있습니다.
2. update으로 설정
- 데이터베이스에 없는 테이블이나 컬럼을 자동으로 추가하지만, 기존 데이터는 삭제하지 않습니다. 애플리케이션이 실행될 때마다 엔티티 클래스와 매핑된 대로 데이터베이스 구조를 업데이트합니다.
- 이 설정을 이용하여 test_users 테이블 생성 뒤, id, name, email 컬럼 생성 후 특정 값을 insert 후, update 해보도록 하겠습니다.
- 이 조건에 의하면, 서버 compile 시 test_users 테이블 생성 후 -> stop이 되어도 데이터가 날라가지 않습니다.
application.yml
yml 파일에 있는 ddl-auto를 update로 변경해보도록 하겠습니다.
jpa:
hibernate:
ddl-auto: update
#ddl-auto: create-drop
나머지 소스는 동일하게 구성한 뒤, compile 해보도록 하겠습니다.
DB 변경 내역
확인해 보면, 2개의 row가 나오는 것을 확인할 수 있습니다.
한 번더, compile 해보도록 하겠습니다.
데이터가 drop & insert 가 아닌, update 되기때문에, 4개의 row를 조회할 수 있습니다.
다음 시간엔 avro type의 데이터를 table에 insert 해보도록 하겠습니다.
(참고용) 일반적인 디렉토리 구조
'Apache Avro' 카테고리의 다른 글
Rest-API 구현 관련 과제 (0) | 2024.10.09 |
---|---|
Spring Boot REST API 및 DB 연동 실습 - 3 (DBtoAvro) (0) | 2024.09.29 |
Spring Boot REST API 및 DB 연동 실습 - 1 (환경설정) (3) | 2024.09.28 |
avro plugin을 이용한 Spring boot 실습 - 3 (avro read) (1) | 2024.09.24 |
avro plugin을 이용한 Spring boot 실습 - 2 (avro write) (1) | 2024.09.24 |
댓글