FrameWork/Spring Boot

DBMS/ ORM/ 스프링 데이터 JPA 조회, 삭제, 추가 메서드, 쿼리 메서드 사용

soooy0 2025. 3. 6. 14:12
DBMS(Database Management System)
DBMS란?
  • 데이터베이스를 관리하기 위한 소프트웨어를 DBMS라고 한다.
  • DB는 많은 사람들이 공유할 수 있어야 하므로 동시 접근을 할 수 있어야 한다.
  • DBMS는 이런 요구사항을 만족하면서도 효율적으로 데이터베이스를 관리하고 운영한다.
  • 우리가 흔히 알고 있는 Oracle, MySQL 등도 DBMS이다.
  • 관계형, 객체=관계형, 도큐먼트형, 비관계형 등으로 분류되며 가장 많이 사용하는 DBMS는 관계형이다.

 

관계형 DBMS(RDBMS = Relational database management system)
  • 관계형 모델을 기반으로 하며 테이블 형태로 이루어진 데이터 저장소이다. 행과 열로 이루어져있다.
  • 회원 테이블이 있다고 가정하면 각 행은 고유의 키(id)를 가지고 있고, 이메일, 나이 등 회원과 관련된 값들이 들어간다.
  • 앞으로 사용할 DB는 H2, MySQL이다.
H2
- 자바로 작성되어 있는 RDBMS이다.
-  스프링부트가 지원하는 인메모리 관계형 데이터베이스
- 데이터를 다른 공간에 따로 보관하는 것이 아니라 애플리케이션 자체 내부에 데이터를 저장하는 특징이 있다. 따라서 애플리케이션이 종료되면 데이터도 초기화된다.
- 간편하게 사용하기 좋아서 테스트 용도로 많이 사용한다. 실제 서비스에서는 사용 안함. 따라서 실제 서비스에서는 MySQL을 사용할 예정

** DB 용어 참고 **
- 테이블: 행과 열로 이루어짐
- 행(record): 반드시 고유한 식별자인 기본키를 가진다
- 열: 행에 저장되는 유형의 데이터, 각 요소에 대한 속성을 나타내며 무결성을 보장한다.
- 기본키: 행을 구분할 수 있는 식별자, 중복 데이터 불가. NULL 불가
- 쿼리: 데이터를 조회, 삭제, 생성, 수정과 같은 처리를 위해 사용하는 명령문

 

ORM(Object-relational mapping)
  • 자바의 객체와 데이터베이스를 연결하는 프로그래밍 기법, 자바 언어로만 데이터베이스를 다룰 수 있게 하는 도구
  • ex)
    • DB에 age = 20, name = '홍길동'이라는 값이 들어있다고 했을 때, 이를 자바에서 사용하려면?
    • 보통은 SQL로 데이터를 꺼내야함 -> SQL을 공부해야함
  • 하지만 이럴 경우 ORM이 있다면 데이터베이스의 값을 마치 객체처럼 사용할 수 있다. 쉽게 말하면 SQL을 몰라도 자바 언어로만 데이터베이스에 접근해서 원하는 데이터를 가져올 수 있는 것이다.
  • ex)
    • Java 코드: int age = 20, String name = "홍길동" ---- ORM ---- RDB: age = 20, name = 홍길동
  • 장점
    • SQL 직접 생성 없이 사용하는 언어로 DB에 접근할 수 있다.
    • 객체지향적으로 코드를 작성할 수 있기 때문에 비즈니스 로직에만 집중할 수 있다.
    • 데이터베이스 시스템에 대한 종속성이 줄어든다.(MySQL -> PostgreSQL로 전환햐도 추가로 드는 작업 거의 없음)
    • 매핑하는 정보가 명확하기 때문에 ERD에 대한 의존도를 낮출 수 있고 유지보수 할 때 유리하다.
  • 단점
    • 프로젝트의 복잡성이 커질수록 사용 난이도도 올라간다
    • 복잡하고 무거운 쿼리는 ORM으로 해결이 불가능한 경우가 있다.
JPA
  • ORM의 여러 종류 중, 자바에서는 JPA(Java Persistence API)를 표준으로 사용한다. 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이다.
  • 자바 객체와 데이터베이스를 연결해 데이터를 관리한다. 객체 지향 도메인 모델과 데이터베이스의 다리 역할을 한다.
  • 인터페이스이기 때문에, 실제 사용을 위해서는 ORM 프레임워크를 추가로 선택해야 한다. 이를 위해 대표적으로는 하이버네이트를 많이 사용한다.
Hirbernate (하이버네이트)
  • JPA 인터페이스를 구현한 구현체이자 자바용 ORM프레임워크이다. 내부적으로는JDBC API를 사용한다.
  • 자바 객체를 통해 데이터베이스 종류에 상관없이 데이터베이스를 자유자재로 사용할 수 있게 한다.

 

JPA - 엔티티 매니저, 영속성 컨텍스트
엔티티
  • 엔티티는 데이터베이스의 테이블과 매핑되는 객체를 의미한다.
  • 엔티티는 본질적으로는 자바 객체이므로, 일반 객체와 다르지 않다. 하지만 데이터베이스의 테이블과 직접 연결된다는 아주 특별한 특징이 있어 구분지어 부른다.
  • 즉, 엔티티는 객체이긴 하지만 데이터베이스에 영향을 미치는 쿼리를 실행하는 객체인 것이다.

 

엔티티 매니저
  • 엔티티 매니저는 엔티티를 관리해 데이터베이스와 애플리케이션 사이에서 객체를 생성, 수정, 삭제하는 등의 역할을 한다. 
  • 엔티티 매니저를 만드는 곳은 엔티티 매니저 팩토리이다.
  • 동시에 요청이 2개 들어왔을 때, 엔티티 매니저 팩토리에서 2개의 엔티티 매니저가 생성되며 각 요청을 처리한다.
  • 스프링 부트에서는 내부에서 엔티티 매니저 팩토리를 하나만 생성해서 관리하고 @PersistanceContext 아니면 @Autowired 애너테이션을 사용해서 엔티티 매니저를 만든다.
    • 스프링 부트는 기본적으로 빈을 하나만 생성해서 공유하므로 동시성 문제가 발생할 수 있다.
    • 따라서 실제로는 엔티티 매니저가 아닌, 실제 엔티티 매니저와 연결하는 프록시(가짜) 엔티티 매니저를 사용한다.
    • 필요할 때 데이터베이스 트랜잭션과 관련된 실제 엔티티 매니저를 호출하는 것이다.
    • 엔티티 매니저는 Spring Data JPA에서 관리하므로 우리가 직접 생성하거나 관리할 필요가 없다.
영속성 컨텍스트
  • 엔티티 매니저는 엔티티를 영속성 컨텍스트에 저장한다는 특징이 있다.
  • 영속성 컨텍스트는 JPA의 특징 중 하나로, 엔티티를 관리하는 가상의 공간이다. 이것이 있기 때문에 데이터베이스에서 효과적으로 데이터를 가져올 수 있고, 엔티티를 편하게 사용할 수 있는 것이다.

1차 캐시

  • 영속성 컨텍스트 내부에는 1차 캐시가 있다. 이때 캐시의 키는 엔티티의 @Id 에너테이션이 달린 기본키 역할을 하는 식별자이며, 값은 엔티티이다.
  • 엔티티를 조회하면 1차 캐시에서 데이터를 조회하고 값이 있으면 반환한다. 값이 없으면 데이터베이스에서 조회해 1차 캐시에 저장한 다음 반환한다.
  • 이를 통해 캐시된 데이터를 조회할 때에는 데이터베이스를 거치지 않아도 되므로 빠르게 데이터를 조회할 수 있다.

 

쓰기 지연

  • 트랜잭션을 커밋하기 전까지는 데이터베이스에 실제로 질의문을 보내지 않고 쿼리를 모았다가 트랜잭션을 커밋하면 모았던 쿼리를 한번에 실행하는 것을 의미한다.
  • ex) 데이터 추가 쿼리가 3개일 경우,
    • 영속성 컨텍스트는 트랜잭션을 커밋하는 시점에 3개의 쿼리를 한꺼번에 전송한다.
    • 이를 통해 적당한 묶음으로 쿼리를 요청할 수 있어 데이터베이스 시스템의 부담을 줄일 수 있다.

변경 감지

  • 트랜잭션을 커밋하면 1차 캐시에 저장되어 있는 엔티티의 값과 현재 엔티티의 값을 비교해서 변경된 값이 있다면 변경 사항을 감지해 변경된 값을 데이터베이스에 자동 반영한다.
  • 쓰기 지연과 마찬가지로 적당한 묶음으로 쿼리를 요청할 수 있고, 데이터베이스 시스템의 부담을 줄일 수 있다.

 

지연 로딩

  • 쿼리로 요청한 데이터를 애플리케이션에 바로 로딩하는 것이 아니라, 필요할 때 쿼리를 날려 데이터를 조회하는 것을 의미한다.
  • 반대로 조회할 떄 쿼리를 보내 연관된 모든 데이터를 가져오는 즉시 로딩도 있다.

 

=> 즉, 모두 데이터베이스의 접근을 최소화하여 성능을 높일 수 있다는 점이다.

 

**참고
엔티티는 4가지의 상태를 가진다. (분리 상태, 관리 상태, 비영속 상태, 삭제 상태)

- 처음 만들면 엔티티는 비영속 상태가 된다.
- persist() 메서드를 사용해 엔티티를 관리 상태로 만들 수 있다. (영속성 컨텍스트의 상태가 관리된다)
- 더이상 관리하고 싶지 않으면 detach() 메서드를 사용해 분리 상태로 만든다.
- 더 이상 객체가 필요 없다면 remove() 메서드를 사용해 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제할 수 있다.

 

 

스프링 데이터와 스프링데이터 JPA
  • 스프링 데이터에서 제공하는 인터페이스를 통해서 스프링 데이터를 사용할 수 있다. 이 인터페이스에는 CRUD(Create, Read, Update, Delete)를 포함한 여러 메서드가 포함되어 있으며, 알아서 쿼리를 만들어준다. + 페이징처리 기능, 자동으로 메서드 이름을 사용하여 빌딩하는 기능 등을 제공한다.
  • JPA는 스프링에서 구현한 스프링 데이터 JPA를, 몽고디비는 스프링 데이터 몽고디비를 사용하는 등, 각 데이터베이스의 특성에 맞춰 기능을 확장해 제공하는 기술도 있다.

 

스프링 데이터 JPA
  • 스프링의 공통적인 기능에서 JPA의 유용한 기술이 추가된 것이다. 스프링 데이터의 인터페이스인 PagingAndSortingRepository를 상속받아 JpaRepository 인터페이스를 만들었으며, JPA를 더 편리하게 사용하는 메서드를 제공한다.
  • 기존에는 Entitymanager와 @PersistenceContext 애너테이션을 사용하여 메서드를 호출하여 상태를 변경했다면,
  • 이젠 스프링 데이터 JPA를 사용하여 레포지터리 역삭을 하는 인터페이스를 만들고, 데이터베이스 테이블의 조회, 수정, 삭제, 생성 등의 작업을 간단히 할 수 있다. JpaRepository 인터페이스를 상속받고, 제네릭에 <엔티티 이름, 엔티티 기본키의 타입>을 입력하여 기본 CRUD메서드를 사용할 수 있다.
public interface MemberRepository extends JapRepository<Member, Long>{
}

 

조회 메서드 사용해보기

 

1. MemberRepository.java 파일에서 테스트 파일을 만든다.

테스트 파일은 클래스 이름을 클릭한 뒤, cmd + shift + t 를 눌러서 생성한다.

 

2. 테스트 파일을 통해 사용법을 익혀볼 것이다. 먼저 조회 메서드를 사용해보자.

  • 원래는 테이블의 모든 데이터를 조회하려면 "SELECT * FROM member"라고 쿼리문을 작성해야했지만, JPA에서는 데이터를 가져올 때 쿼리를 작성하는 대신 findAll() 메서드를 사용하면 된다.
  • 우선 데이터를 조회하려면 데이터가 필요하니, 테스트용 데이터를 추가해보자.
    • [test] - [resources]에 우클릭 -> insert-members.sql 파일 생성 후, 쿼리문 작성
INSERT INTO member(id, name) VALUES (1, 'A')
INSERT INTO member(id, name) VALUES (2, 'B')
INSERT INTO member(id, name) VALUES (3, 'C')
  • application.yml 파일에 코드 작성, data.sql 파일이 자동으로 실행되지 않게 해주는 옵션이다.
Spring:
    sql:
      init:
        mode: never

 

**참고
Q. yml 파일이 뭘까?
A. YAML(.yml, .yaml) 파일은 설정(Configuration) 파일을 작성할 때 사용되는 포맷이다. Spring Boot에서는 application.yml 파일을 사용해서 서버, 데이터베이스, 보안 등 애플리케이션의 환경 설정을 관리 할 수 있다. 

Spring Boot에서는 환경 설정을 application.properties 나 application.yml 에서 설정할 수 있다. 둘 다 같은 기능을 하지만,
yml이 더 가독성이 좋아서 많이 사용된다.


1️⃣ application.properties 방식
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=1234

2️⃣ application.yml 방식
server:
   port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: 1234
  • 이제 데이터를 잘 가져오는지 검증하는 테스트 코드를 작성한다.
package me.jinsoyeong.springbootdeveloper;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.jdbc.Sql;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
class MemberRepositoryTest {
    @Autowired
    MemberRepository memberRepository;

    /*
    * @SQL: 테스트 실행 전 SQL 스크립트를 실행시킬 수 있다. insert-members.sql에 적은 insert문을 실행하게 되는 것*/
    @Sql("/insert-members.sql")
    @Test
    void getAllMembers() {
        // when
        List<Member> members = memberRepository.findAll();

        // then
        assertThat(members.size()).isEqualTo(3);
    }
}

 

  • 실행해보면 잘 테스트가 성공된 모습을 볼 수 있다.
  • 디버그 모드를 사용해 객체를 확인해보자. 검증문을 작성한 assertThat 줄의 번호를 눌러 빨간색 원 표시를하고, 디버그 모드를 실행한다.

  • SQL 문으로 추가한 데이터인 A, B, C 멤버의 정보를 확인할 수 있다.
  • 이번엔 id로 멤버를 찾아보도록 하자. id = 2인 멤버를 찾아보자.
    • 쿼리문으로 작성하면: SELECT * FROM member WHERE id = 2;
    • JPA로 작성하면
@Sql("/insert-members.sql")
@Test
void getMemberById(){
    // when
    // SELECT * FROM member WHERE id = 2;
    Member member = memberRepository.findById(2L).get();

    // then
    assertThat(member.getName()).isEqualTo("B");
}
  • 테스트를 돌려보면 잘 동작되는 것을 볼 수 있음

 

쿼리 메서드 사용해서 조회 해보기
  • Id는 기본키로 사용하기 때문에 Null이 존재할 수 없다. 하지만 name의 경우, 값이 없을 수 있다.
  • JPA에서 기본으로 name을 찾아주는 메서드를 지원하지는 않지만, JPA는 메서드 이름으로 쿼리를 작성하는 기능을 제공한다.

1. name의 값이 'C'인 멤버를 찾아야 하는 경우 쿼리문

  • 쿼리문: SELECT * FROM member WHERE name = 'C';

2. 이 쿼리문을 동적 메서드로 만들어보기

  • MemberRepository.java 파일을 열어서 findByName()메서드를 추가한다.
package me.jinsoyeong.springbootdeveloper;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByName(String name);
}
  • 상속 받아 구현할 필요도 없이 그냥 메서드로 정의한 후 가져다 쓰기만 하면 된다.

3. MemberRepositoryTest.java 파일로 이동하여 test가 잘 작동되는지 확인한다.

@Sql("/insert-members.sql")
@Test
void getMemberByName(){
    // when
    Member member = memberRepository.findByName("C").get();

    // then
    assertThat(member.getId()).isEqualTo(3);
}

테스트가 정상적으로 실행된 모습

 

**참고
@Query 메서드로 SQL뭐리문 작성해보기
- JPA를 이용하여 표현하기 너무 복잡한 쿼리이거나 성능이 너무 중요해서 SQL 쿼리문을 직접 사용해야 하는 경우도 있다. 이럴 때는 @Query메서드를 사용한다.

@Query("select m from Member m where m.name = ?1")
Optional<Member> findByNameQuery(String name);

 

추가 메서드 사용해보기

 

  • 데이터를 추가하기 위해 필요한 쿼리문
    • INSERT INTO member(id, name) VALUES (1, 'A'); 
  • 데이터를 추가하기 위해 JPA에서 사용하는 메서드
    • save()
테스트 코드로 save() 메서드 사용해보기
// 추가 메서드 사용해보기
// 이미 추가된 데이터가 있으면 안되므로 @Sql 애너테이션 사용하지 않음
@Test
void saveMember(){
    // given, 테스트 데이터 준비
    // 새로운 A멤버 객체를 준비
    Member member = new Member(1L, "A");

    // when, 데이터 저장
    // 위에 생성한 member 객체가 실제로 데이터베이스에 저장됨
    memberRepository.save(member);

    // then, 저장된 값 검증
    // id = 1에 해당하는 멤버의 이름 가져오기
    /*
    * memberRepository.findById(1L).get() → ID가 1L인 멤버를 데이터베이스에서 조회
    * .getName() → 조회한 멤버(id가 1인 멤버)의 name 값을 가져옴
    * assertThat(...).isEqualTo("A"); → 저장된 데이터(가져온 데이터)의 이름이 "A"와 같은지 검증
    * */
    assertThat(memberRepository.findById(1L).get().getName()).isEqualTo("A");
  • 한꺼번에 여러 엔티티를 저장하고 싶다면 saveAll() 메서드를 사용할 수도 있다.
@Test
// 한꺼번에 여러 엔티티를 저장하는 경우
// 추가할 멤버 객체들을 리스트로 만들고 saveAll() 메서드로 한꺼번에 추가한 후, 추가한 멤버 객체 수만큼 데이터에 있는지 확인
void saveMembers(){
    // given, 테스트 데이터 준비
    List<Member> members = List.of(new Member(2L,"B"), new Member(3L, "C"));

    // when, 데이터 저장
    memberRepository.saveAll(members);

    // then, 검증
    // 저장된 데이터의 수가 2개가 맞는지 검증
    assertThat(memberRepository.findAll().size()).isEqualTo(2);

}

 

 

삭제 메서드 사용해보기
  • 데이터를 삭제하기 위해 필요한 쿼리문
    • DELETE FROM member WHERE id = 2; 
  • 데이터를 삭제하기 위해 JPA에서 사용하는 메서드
    • deleteById();
테스트 코드로 deleteById() 메서드 사용해보기
// 삭제 메서드 사용해보기
/* insert-members.sql을 실행하여 3명의 멤버를 추가하고 deleteById() 메서드를 사용하여 id = 2인 멤버를 삭제한 뒤,
* id = 2인 멤버가 있는지 조회, 삭제된 데이터이므로 isEmpty = true로 검증
* */
@Sql("/insert-members.sql")
@Test
void deleteMemberById(){
    // when
    memberRepository.deleteById(2L);

    // then
    assertThat(memberRepository.findById(2L).isEmpty()).isTrue();
}
  • 검증문에 브레이크 포인트를 잡고, 디버그 모드로 실행 -> 디버그 창의 구문 실행바에 memberRepository.findAll()을 입력 -> result라는 결과가 나오며 B를 제외한 A, C만 남은 것을 확인 가능하다.

  • 한꺼번에 여러 엔티티를 저장하고 싶다면 deleteAll() 메서드를 사용할 수도 있다.
// 모든 데이터 삭제해보기
@Sql("/insert-members.sql")
@Test
void deleteAllMember(){
    // when
    memberRepository.deleteAll();

    // then
    assertThat(memberRepository.findAll().isEmpty()).isTrue();
}

 

  • 하지만 모든 데이터를 삭제하기 때문에, 실제 서비스 코드에서는 거의 사용하지 않는다.
  • 보통 deleteAll() 메서드는 테스트 간의 격리를 보장하기 위해 사용된다. 즉, 한 테스트의 실행으로 데이터베이스가 변경되었을 경우 다른 테스트가 그 데이터베이스를 사용할 때 영향을 주지 않도록 하기 위함이다.
  • 따라서 보통은 @AfterEach 애너테이션을 붙여 cleanUp() 메서드와 같은 형태로 사용한다.
@DataJpaTest
class MemberRepositoryTest{
    @Autowired
    MemberRepository memberRepository;
    
    @AfterEach
    public void cleanUp(){
        memberRepository.deleteAll();
    }
}

 

수정 메서드 사용해보기

 

  • 데이터를 수정하기 위해 필요한 쿼리문
    • UPDATE member SET name = 'BC' WHERE id = 2;
  • 데이터를 수정하기 위해 JPA에서 사용하는 메서드, 이때 JPA는 트랜잭션 내에서 데이터를 수정해야 하기 때문에 그냥 메서드만 사용하는 것이 아닌, @Transactional 애너테이션을 메서드에 추가해야 한다.
    • @Transactional
테스트 코드로 @Transactional 애너테이션 사용해보기

 

1. Member.java 파일에 메서드 추가

// name의 필드값을 바꾸는 메서드
public void chanename(String name){
    this.name = name;
}
  • 이 메서드가 @Transactional 애너테이션이 포함된 메서드에서 호출되면, JPA는 변경 감지 기능을 통해 엔티티의 필드값이 변경될 때, 그 변경 사항을 데이터베이스에 자동으로 반영한다.
  • 만약 엔티티가 영속 상태일 때 필드값을 변경하고 트랜잭션이 커밋된다면, JPA는 변경 사항을 데이터베이스에 자동으로 적용한다.

2. MemberRepositoryTest.java에 코드 추가

// 수정 메서드 사용해보기
// insert-member.sql 스크립트로 3명의 멤버 추가
@Sql("/insert-member.sql")
@Test
void update(){
    // given, 데이터 준비
    // 추가된 데이터에서 id = 2인 멤버를 찾음
    Member member = memberRepository.findById(2L).get();

    // when
    // 위에서 찾은 id = 2인 멤버의 이름을 changeName()를 사용하여 "BC"로 변경
    member.changeName("BC");

    // then id = 2인 멤버의 name을 가져와서 "BC"와 같은지 검증
    assertThat(memberRepository.findById(2L).get().getName()).isEqualTo("BC");
}
  • 여기서 잠깐, @Transactional 애너테이션이 없는데도 잘 실행되는 모습이다. 그 이유는?
    • MemberRepositoryTest 파일 상단에 보면 @DataJpaTest 애너테이션을 사용했기 때문이다.
    • @DataJpaTest 애너테이션은 테스트를 위한 설정을 제공하며 자동으로 데이터베이스에 대한 트랜잭션 관리를 설정한다.
    • cmd + 애너테이션을 클릭해서 세부 항목을 살펴보면 @Transactional 애너테이션이 있다.

  • 하지만 서비스 코드에서 이 수정 기능을 사용하려면, 해당 메서드에 반드시 @Transactional 애너테이션을 추가해주어야 한다.

 

Member.java 파일 코드 살펴보기

 

앞전에 작성한 Member.java 클래스의 각 코드를 뜯어보자.

package me.jinsoyeong.springbootdeveloper;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자
@AllArgsConstructor
@Getter
@Entity // 엔티티로 지정
public class Member {
    @Id // id필드를 기본키로 지정
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 기본키를 자동으로 1씩 증가
    @Column(name = "id", updatable = false)
    private Long id; // DB 테이블의 'id' 컬럼과 매칭

    @Column(name = "name", nullable = false) // name이라는 not null 컬럼과 매칭
    private String name; // DB 테이블의 'name' 컬럼과 매칭

    // name의 필드값을 바꾸는 메서드
    public void changeName(String name){
        this.name = name;
    }
}
@Entity
  • Member 객체를 JPA가 관리하는 엔티티로 지정한다.
  • Member 클래스와 실제 데이터베이스의 테이블을 매핑하는 것.
  • @Entity 속성 중 name을 사용하면, name의 값을 가진 테이블 이름과 매핑되고, 테이블 이름을 지정하지 않으면 클래스 이름과 같은 이름의 테이블과 매핑된다.
  • 여기서는 테이블 이름을 지정하지 않았으므로 클래스 이름과 같은 member 테이블과 매핑된다.
테이블을 지정하고 싶다면?

ex) member_list라는 이름을 가진 테이블과 매핑
@Entitiy(name = "member_list")
public class ... {
....

 

@NoArgsConstructor(access = AccessLevel.PROTECTED)
  • protected 기본 생성자이다.
  • 엔티티는 반드시 기본 생성자가 있어야 하고, 접근제어자는 public or protected 이어야 한다. (public 보다 protected가 안전)
@AllArgsConstructor
  • 모든 필드를 포함하는 생성자를 자동으로 생성, ex) new Member(id, name)과 같은 생성자가 자동으로 만들어짐
@Getter
  • 모든 필드에 대한 Getter 메서드를 자동으로 생성, ex) getName()
@Id
  • Long타입의 id필드를 테이블의 기본키로 지정
@GeneratedValue
  • 기본키의 생성 방식을 결정하는 애너테이션
  • @GeneratedValue(strategy = GenerationType.IDENTITY) = 자동으로 기본키가 1씩 증가되도록 지정
** 자동키 생성 설정 방식
- AUTO: 선택한 데이터베이스에 따라 방식을 자동으로 선택(default)
- IDENTITY: 기본키 생성을 데이터베이스에 위임 = (AUTO_INCREMENT)
- SEQUENCE: 데이터베이스 시퀀스를 사용해서 기본키에 할당하는 방법, 주로 오라클에서 사용
- TABLE: 키 생성 테이블 사용

 

@Column
  • 데이터베이스의 컬럼과 필드를 매핑해줌
  • @Column 애너에티션 속성
    • name: 필드와 매핑할 컬럼 이름, 설정하지 않으면 이름으로 지정해줌
    • nullable: 컬럼의 null 허용 여부, 설정하지 않으면 true(nullable)
    • unique: 컬럼의 유일한 값(unique) 여부, 설정하지 않으면 false(non unique)
    • columnDefinition: 컬럼 정보 설정, default 값을 줄 수 있음

 

MemberRepository 파일 코드 살펴보기

 

// Repository 파일은 엔티티에 있는 데이터들을 조회하거나 저장, 변경, 삭제 할 때 사용하는 인터페이스이다.
// 스프링 데이터 JPA에서 제공하는 인터페이스인 JpaRepository 클래스를 상속받아 간단하게 구현할 수 있다.
@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByName(String name);
}

 

 

JPA는 자바 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스
하이버네이트는 인터페이스인 JPA를 구현하기 위한 구현체, ORM 프레임워크
스프링데이터 JPA는 JPA를 편리하게 쓰기 위해 만들어 놓은 모듈

헷갈리지 말기!