Spring Boot :: JPA 기초 ( 2 )

JaeHwan·2023년 9월 1일
0

Spring Boot

목록 보기
7/8

🍃 JPA 기초 ( 2 )

☸️ 기초설정

사용하는 설정파일의 확장자에따라 설정법이 다르겠지만 나는 yml 을 사용하기 때문에 yml로 글을 쓰겠다. 일반적으로 Spring Data JPA 를 사용하여 DB 와 연결을 하려면 설정파일에서 관련 코드를 적어줘야한다.

spring:
  datasource:
    url: [DB 접근 경로]
    username: [DB 계정 id]
    password: [DB 계정 비밀번호]

  jpa:
    database-platform: [사용하는 DB에 맞게]
    hibernate:
      ddl-auto: [해당사항에 맞게]
    properties:
      hibernate:
        format_sql: [log에 표시되는 sql의 포맷 설정]
    show-sql: [SQL 쿼리를 볼 것인지]

기본적으로 auto-ddl 은 중요하다. Table의 schema를 만드는 기준을 설정해주는 것이기 때문이다. 해당 기준은 여러 것이 있다.

  • none : 기본 관리를 위해 어떤 조치도 취하지 않음, hibernate는 개발자를 위해 데이터베이스 스키마를 생성하지 않는다.

  • create-only : Spring Boot 에서 생성하는 모든 JPA 모델에 대한 모든 테이블을 생성하도록 hibernate에 지시

  • drop : 데이터베이스 스키마를 삭제하기 위해 hibernate에 지시, JPA 엔터티를 참조하여 모든 테이블을 삭제하도록 지시

  • create : 이 옵션은 hibernate에 기존 데이터베이스 스키마를 삭제하고 다시 생성하도록 지시. Spring boot 에서 생성한 JPA 모델을 참조하여 모든 테이블을 생성

  • create-drop : JPA 모델을 참조 모든 테이블을 생성, 그리고 일단 엔터티 관리 팩토리나 hibernate 세션 팩토리가 닫히면 모든 것을 다시 삭-제

  • validate : 엔터티에 대해 기본 데이터베이스 스키마의 유효성을 검사하도록 만든다. 엔터티 매핑을 사용하여 데이터베이스의 유효성을 검사

  • update : 기존 스키마를 업데이트 하도록 hibernate 지시 JPA 엔터티에서 수행한 모든 변경 사항을 적용, 이 과정에서 기존 값은 삭제하지 않는다. JPA 엔터이에서 수행하는 변경 사항이 무엇이든 테이블을 변경한다.

기본적으로 위의 사항들 중 원하는 또는 해야하는 옵션을 선택해서 코드를 작성하면 좋을 것이다.

📖 Table 생성

@Entity
@Table(
    name = "tb_product",
    uniqueConstraints = { // 유니크 컬럼 설정법
        @UniqueConstraint(
            name = "sku_unique",
            columnNames = "stock_keeping_unit"
        )
    }
)
public class Product {
    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "product_generator"
    ) // Not good for JDBC batch operations
    @SequenceGenerator(
            name = "product_generator",
            sequenceName = "product_sequence_name",
            allocationSize = 1
    )
    private Long id;
    @Column(name = "stock_keeping_unit", nullable = false) // column 에 대한 세세한 설정할 때 사용
    private String sku; // Stuck keeping Unit
    @Column(nullable = false)
    private String name;
    private String description;
    private BigDecimal price;
    private boolean active;
    private String imageUrl;
    @CreationTimestamp
    private LocalDateTime dateCreated;
    @UpdateTimestamp
    private LocalDateTime lastUpdated;
}

PrimaryKey 즉, id에 대한 키값 설정에는 다양한 방법이 있다.
기본적으로 @GeneratedValue를 이용해 strategy 속성으로 설정해준다.

  • AUTO: 기본 키 값을 자동으로 생성하며, 데이터베이스의 종류에 따라 자동 생성 전략이 달라진다. 주로 데이터베이스에게 키 생성을 위임한다.

  • IDENTITY: 데이터베이스가 기본 키 값을 자동으로 생성한다. 주로 MySQL, PostgreSQL 등에서 사용된다.

  • SEQUENCE: 시퀀스(generator)를 사용하여 기본 키 값을 생성한다. 주로 Oracle 데이터베이스와 같은 시퀀스를 지원하는 데이터베이스에서 사용된다.

  • TABLE: 데이터베이스 테이블을 사용하여 기본 키 값을 생성한다. 특정 데이터베이스 테이블을 생성하여 그 안에서 시퀀스를 관리한다.

나는 보통 JPA 를 이용해 Table 을 만들 때 key 값을 identity로 auto-increasement를 즐겨 썼다. 하지만 내가 듣는 강의에서 sequence 를 이용해 sequence table을 생성하고 sequence를 관리하는 것이 더 효율적이라고 들었다. 그 이유에 대해서 여러가지 검색하고 찾아보았는데

우선, sequence table 에서 sequence를 관리하고 다음 값을 미리 저장하고 있기 때문에 insert 할 때 auto-increasement 처럼 계산을 해주면서 값을 넣어줄 필요가 없어서 조금 더 데이터베이스의 효율이 올라간다고한다.
다음 이유는 auto-increasement를 사용할 경우 값이 동시에 들어오면 key 의 sequence 에 대해서 어떤 값을 넣어줘야할지 DB가 제대로 정하지 못해 동시성 문제가 생긴다면 sequence table 을 만들고 관리한다면 그 table 에 다음 sequence 값이 이미 들어있기 때문에 동시성 문제가 어느정도 해결된다. 는 것이다.

정리하자면

  • 다음 값을 sequence table 에서 이미 가지고 있기 때문에 DB 효율성이 더 올라간다.
  • 동시성이 어느정도 제어된다.

가 있었다.

참조

https://www.udemy.com/course/building-real-time-rest-apis-with-spring-boot/

profile
Flutter를 사랑하는 근데 이제 백엔드를 곁들인

0개의 댓글