Framework/Springboot

[Springboot] DB설정 / JPA

웹개발자(진) 2024. 5. 9. 22:23
반응형
잡담

Springboot를 공부하면서 annotation도 너무 많고, 구조적으로도 이해 안 되는 부분이 많아서 공부하는데 애를 먹고 있습니다. 계속 연습하다 보면 왜 Springboot를 쓰는지 이해할 날이 올 거라 믿습니다. 오늘은 JPA에 대해 알아볼 예정입니다. JPA를 이용해서 데이터베이스와 독립적인 쿼리 작성이 가능하며, 엔티티에 대한 직관적인 쿼리 작성이 가능합니다. 또한 매핑을 지원해서 자바언어로 데이터베이스를 다룰 수 있게 됩니다. JPA는 최근에 많이 사용하기 때문에 잘 배워둬야 될 것입니다.


 

1. JPA

JPA(Java Persistence API)는 자바 애플리케이션에서 데이터를 관리하고 영구 저장하는 데 사용되는 자바 ORM(Object-Relational Mapping) 표준입니다. JPA는 객체와 관계형 데이터베이스 간의 매핑을 단순화하고 객체 지향적인 방식으로 데이터를 처리할 수 있도록 지원합니다.

JPA는 다음과 같은 주요 기능을 제공합니다:

  1. 객체-관계 매핑(ORM): JPA는 자바 클래스와 관계형 데이터베이스 테이블 간의 매핑을 지원합니다. 즉, 개발자가 객체 지향 프로그래밍 언어인 자바로 데이터베이스를 다룰 수 있게 해 줍니다.
  2. CRUD 작업 지원: JPA는 객체의 생성(Create), 읽기(Read), 갱신(Update), 삭제(Delete)와 같은 기본적인 데이터베이스 작업을 지원합니다.
  3. JPQL(Java Persistence Query Language): JPA는 개체에 대한 데이터베이스 쿼리를 작성하기 위한 JPQL이라는 객체 지향 쿼리 언어를 제공합니다. 이를 통해 데이터베이스와 독립적인 쿼리 작성이 가능하며, 엔티티에 대한 직관적인 쿼리 작성이 가능합니다.
  4. 캐싱: JPA는 캐시를 사용하여 성능을 향상할 수 있습니다. 엔티티와 쿼리 결과를 캐시 하여 반복적인 데이터베이스 접근을 피하고 성능을 향상합니다.
  5. 트랜잭션 관리: JPA는 트랜잭션 관리를 지원하여 데이터베이스 작업을 안전하게 수행할 수 있도록 합니다.

Spring Framework에서는 JPA를 지원하는 Spring Data JPA와 함께 사용될 수 있으며, Spring Boot에서는 JPA를 쉽게 설정하고 사용할 수 있는 다양한 기능을 제공합니다. JPA를 사용하면 개발자는 데이터베이스와의 상호작용을 보다 쉽고 효율적으로 처리할 수 있습니다.


2. Board 생성

 

1. @Entity

@Entity 어노테이션은 JPA(Java Persistence API)에서 엔티티 클래스를 표시하기 위해 사용됩니다. 엔티티 클래스는 데이터베이스의 테이블과 매핑되는 자바 객체를 나타냅니다. 즉, 데이터베이스의 테이블과 자바 객체 간의 매핑을 위해 사용됩니다.

@Entity 어노테이션을 사용하여 클래스를 엔티티로 표시하면, 해당 클래스의 객체를 데이터베이스에 저장할 수 있습니다. 엔티티 클래스는 데이터베이스의 테이블에 저장되는 각 열(column)을 매핑하는 필드를 포함합니다.

예를 들어, 다음은 @Entity 어노테이션을 사용하여 간단한 엔티티 클래스를 정의하는 예제입니다:

해당 예제는 DB Table에 게시판에 관련된 칼럼을 변수로 주는 코드입니다.

package org.zerock.b02.domain; // 클래스의 패키지 선언

import jakarta.persistence.*; // JPA 관련 어노테이션 import
import lombok.*; // Lombok 관련 어노테이션 import

@Entity // JPA에서 엔티티 클래스임을 나타내는 어노테이션
@Getter // Lombok을 사용하여 Getter 메서드 생성
@Builder // Lombok을 사용하여 빌더 패턴 지원
@AllArgsConstructor // Lombok을 사용하여 모든 필드를 매개변수로 받는 생성자 생성
@NoArgsConstructor // Lombok을 사용하여 기본 생성자 생성
@ToString // Lombok을 사용하여 toString() 메서드 생성
public class Board extends BaseEntity{ // Board 클래스 선언, BaseEntity를 상속

    @Id // 기본 키(primary key)임을 나타내는 어노테이션
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 기본 키 생성 전략 설정
    private long bno; // 게시물 번호 필드

    @Column(length = 500, nullable = false) // 컬럼 설정
    private String title; // 제목 필드

    @Column(length = 2000, nullable = false)
    private String content; // 내용 필드

    @Column(length = 500, nullable = false)
    private String writer; // 작성자 필드
}

이 코드는 Board 클래스를 JPA의 엔티티로 지정하고 있습니다. @Entity 어노테이션은 해당 클래스가 데이터베이스의 테이블과 매핑되는 엔티티 클래스임을 나타냅니다.

게시판에 관련된 정보인 제목(title), 내용(content), 작성자(writer)를 나타내는 필드들이 정의되어 있습니다. 이러한 필드들은 각각 @Column 어노테이션을 사용하여 데이터베이스의 칼럼과 매핑되어 있습니다.


2. @Id / @GeneratedValue

@Id 어노테이션은 엔티티의 기본 키(primary key)를 나타내며, @GeneratedValue 어노테이션을 통해 기본 키의 생성 전략을 설정할 수 있습니다. 이 경우는 데이터베이스에서 자동으로 생성되는 IDENTITY 전략을 사용하고 있습니다.

Java Persistence API(JPA)에서는 다양한 기본 키 생성 전략을 제공합니다.

1. IDENTITY: 데이터베이스가 기본 키 값을 자동으로 생성하도록 하는 전략입니다. 대부분의 관계형 데이터베이스에서 지원됩니다. 데이터베이스의 자동 증가(auto-increment) 기능을 사용하여 기본 키 값을 생성합니다.

@GeneratedValue(strategy = GenerationType.IDENTITY)

2. SEQUENCE: 데이터베이스의 시퀀스(sequence)를 사용하여 기본 키 값을 생성하는 전략입니다. 시퀀스는 데이터베이스에서 일련번호를 생성하는 객체로, 시퀀스에 의해 생성된 값을 사용하여 기본 키 값을 할당합니다.

@GeneratedValue(strategy = GenerationType.SEQUENCE)

3. TABLE: 데이터베이스의 특별한 테이블을 사용하여 기본 키 값을 생성하는 전략입니다. 특별한 테이블에는 다음에 할당할 기본 키 값을 저장하고 관리하는 열(column)이 포함되어 있습니다.

@GeneratedValue(strategy = GenerationType.TABLE)

그 외에도 JPA는 GenerationType 열거형에 다른 전략들을 제공합니다. 예를 들어, AUTO 전략은 JPA 구현체에게 기본 키 생성 전략을 자동으로 선택하도록 합니다. JPA 구현체는 해당 데이터베이스에 가장 적합한 전략을 선택하여 사용합니다.

@GeneratedValue(strategy = GenerationType.AUTO)

또한, Lombok의 어노테이션들을 사용하여 Getter, Builder, 생성자 등을 자동으로 생성하고 있습니다. 이를 통해 코드의 가독성을 높이고 개발 생산성을 향상할 수 있습니다.


3. @Column

  1. name: 엔티티 필드를 매핑할 데이터베이스 칼럼의 이름을 지정합니다. 기본값은 엔티티 필드의 이름입니다.
  2. nullable: 해당 칼럼이 NULL 값을 허용하는지 여부를 지정합니다. 기본값은 true로, NULL 값을 허용합니다.
  3. unique: 해당 칼럼의 값이 고유해야 하는지 여부를 지정합니다. 기본값은 false로, 중복된 값이 허용됩니다.
  4. length: 해당 칼럼의 길이를 지정합니다. 문자열 컬럼의 경우에만 사용됩니다. 기본값은 255입니다.

외에도 다양한 설정 값들이 존재합니다. DB에서 설정하는 길이나 not null 등의 설정들을 @Column에서 지정해 줄 수 있습니다. 

 


 

3. BaseEntity 생성

이 코드는 Spring Data JPA에서 엔티티의 생성일자 및 수정일자를 관리하기 위한 BaseEntity 클래스입니다. 여기에는 다음과 같은 내용이 포함되어 있습니다:

  1. @MappedSuperclass: 이 어노테이션은 해당 클래스가 테이블로 매핑되지 않지만, 자식 클래스들에게 매핑 정보를 상속하기를 원할 때 사용됩니다. 즉, 이 클래스의 필드들은 자식 엔티티들에 의해 공유됩니다.
  2. @EntityListeners: 이 어노테이션은 엔티티의 상태 변화를 감지하고 처리하는 리스너 클래스를 지정합니다. 여기서는 AuditingEntityListener를 사용하여 엔티티의 생성일자 및 수정일자를 자동으로 업데이트합니다.
  3. @CreatedDate: 이 어노테이션은 엔티티가 생성될 때 자동으로 해당 필드를 현재 날짜 및 시간으로 설정합니다.
  4. @LastModifiedDate: 이 어노테이션은 엔티티가 수정될 때 자동으로 해당 필드를 현재 날짜 및 시간으로 설정합니다.
  5. @Getter: Lombok을 사용하여 자동으로 Getter 메서드를 생성합니다.

이 클래스를 상속하는 다른 엔티티 클래스에서는 regDate 및 modDate 필드를 직접 사용할 필요 없이, 이 클래스가 제공하는 생성일자 및 수정일자 관리 기능을 활용할 수 있습니다.

package org.zerock.b01.domain;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@MappedSuperclass
@EntityListeners(value={AuditingEntityListener.class})  //entity의 상태를 지켜본다. board에서 데이터가 입력,수정되면 EntityListeners가 동작을하게된다.
@Getter
public class BaseEntity {

    @CreatedDate    //생성될때
    @Column(name="regdate",updatable=false)
    private LocalDateTime regDate;

    @LastModifiedDate
    @Column(name="moddate")
    private LocalDateTime modDate;
}

 


 

4. Repository

package org.zerock.b01.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.zerock.b01.domain.Board;

public interface BoardRepository extends JpaRepository<Board, Long> {}

이 코드는 Spring Data JPA에서 사용되는 Repository 인터페이스를 정의하는데, JpaRepository를 상속하여 Board 엔티티에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행합니다.

  • public interface BoardRepository extends JpaRepository <Board, Long> {}JpaRepository를 확장하여 Board 엔티티와 해당 엔티티의 기본 키 타입(Long)을 제네릭으로 지정합니다. 이 인터페이스는 Board 엔티티에 대한 Spring Data JPA 리포지토리를 정의합니다. JpaRepository에서 이미 CRUD 작업을 지원하므로 추가적인 메서드를 선언할 필요가 없습니다.

JpaRepository 인터페이스는 기본적으로 다음과 같은 CRUD 메서드를 제공합니다:

  1. Save 메서드
    • save(S entity): 엔티티를 저장하거나 업데이트합니다.
    • saveAll(Iterable<S> entities): 여러 개의 엔티티를 저장하거나 업데이트합니다.
  2. Delete 메서드
    • deleteById(ID id): 주어진 ID에 해당하는 엔티티를 삭제합니다.
    • delete(T entity): 주어진 엔티티를 삭제합니다.
    • deleteAll(): 모든 엔티티를 삭제합니다.
    • deleteAll(Iterable<? extends T> entities): 여러 개의 엔티티를 삭제합니다.
  3. Find 메서드
    • findById(ID id): 주어진 ID에 해당하는 엔티티를 찾습니다.
    • findAll(): 모든 엔티티를 찾습니다.
    • findAllById(Iterable<ID> ids): 주어진 ID에 해당하는 모든 엔티티를 찾습니다.
    • existsById(ID id): 주어진 ID에 해당하는 엔티티가 존재하는지 여부를 확인합니다.
    • count(): 저장된 엔티티의 총 수를 반환합니다.
  4. 기타 메서드
    • flush(): 영속성 컨텍스트의 변경사항을 데이터베이스에 즉시 반영합니다.
    • getOne(ID id): 지정된 ID에 대한 엔티티의 레퍼런스를 반환합니다.
    • findById(ID id)를 사용하여 엔티티를 찾을 때, 결과가 없을 경우 Optional로 감싸진 객체를 반환합니다. 이를 이용하여 NullPointerException을 방지할 수 있습니다.

 

5. Application

package org.zerock.b01;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class B01Application {

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

}
  • @SpringBootApplication: 이 어노테이션은 Spring Boot 애플리케이션의 주 진입점이 되는 클래스에 부여됩니다. 이 어노테이션이 부여된 클래스는 다음을 포함하는 것으로 간주됩니다.
    • @Configuration: Spring의 설정 클래스임을 나타냅니다.
    • @EnableAutoConfiguration: Spring Boot의 자동 구성을 활성화합니다.
    • @ComponentScan: 컴포넌트 검색을 통해 다른 컴포넌트, 구성 및 서비스를 검색합니다.
  • public static void main(String [] args) {... }: 애플리케이션의 메인 메서드입니다. 이 메서드는 SpringApplication 클래스의 run 메서드를 호출하여 Spring Boot 애플리케이션을 시작합니다. 인자로는 현재 클래스의 클래스 객체와 커맨드 라인 인자들이 전달됩니다.

 


 

글을 마치며

오늘은 JPA와 Annotation을 이용해서 DB table생성 및 설정을 하는 방법을 알아봤습니다. 해당 작업을 진행하면 DB를 직접 열어서 생성할 필요도 없고 나중에 data를 넣는 데 있어서도 SQL문을 사용하지 않더라도 동적으로 데이터를 SELECT, INSERT, DELETE, UPDATE를 할 수 있습니다. 지금은 이해하기 힘들지만 반복해서 사용하는 만큼 이해할 수 있도록 노력해야겠습니다. 감사합니다.

반응형

'Framework > Springboot' 카테고리의 다른 글

[Springboot] thymeleaf 조건문 if  (0) 2024.05.31
[Springboot] Session이란?  (0) 2024.05.30
[Springboot] Scope란?  (0) 2024.05.30
[Springboot] Controller (get / post)  (0) 2024.05.09
[Springboot] Springboot 기본  (0) 2024.05.08