웹개발/Spring Boot

[ SpringBoot] JPA Entity Mysql 연동 과정

BEOTIZA♥ 2024. 2. 20. 23:15

mysql데이터베이스 연동과 JPA를 사용하는 과정을 기록해보려고 한다.

1. dependencies 추가

  JAP,  mysql 의존성을 추가한다

dependencies {	
	// spring-boot-jpa
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

	// mysql
	runtimeOnly 'com.mysql:mysql-connector-j'
    }

 

2. application.yml 에   DB정보 추가하기

  • applicatdion.yml : 스프링부트와 같은 스프링 프로젝트 기반 어플리케이션에서 사용되는 설정 파일
  • 만약 application.properties 가 있다면, 어플을 실행시킬시 properties 설정이 먼저 실행됨.
    • spring / DataSource Configuration
    • Mysql 연결을 위한 설정들
    • JPA/Hibernate Configuration
    • 하이버네이트는 JPA의 구현체로, 자바 객체와 데이터 베이스 테이블 사이의 매핑을 관리해주는 ORM(Object-Relational-Mapping)
    • ddl-auto  DDL 옵션
    • update : 어플리케이션 시작시 데이터베이스 스키마를 업데이트함
    • create : 어플리케이션 시작시 새로운 데이터베이스 스키마 생성, 기존 스키마는 사라짐. 어플리케이션 종료시 데이터 남아있음.
    • create-drop : 어플리케이션 시작시 새로운 스키마를 생성하고, 어플리케이션 종료시 스키마를 삭제함.
server:
  port: 8080
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: true
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/[DB명]?serverTimezone=Asia/Seoul
    username: 어쩌구저쩌구
    password: 어쩌구저쩌구

  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL57Dialect
        show_sql: true

3. Entity

  • 실제 세계의 객체나 개념을 소프트웨어 내에서 모델링 한 것으로, 데이터 베이스의 테이블에 해당하는 클래스
     * 주의
     * 데이터의 일관성을 위해 setter 사용을 지양해야 한다
     * setter를 사용한다면 어디에서든 Entity를 수정해버릴 수 있기 때문에 일관성을 유지하기 어렵다.
  • 어노테이션 정리  
    • @Entity : JPA Entity라는 것을 의미. ID와 @GeneratedValue를 이용해 고유 식별자를 정의한다
    • @Builder : 빌더 디자인 패턴을 자동으로 생성해준다.
    • @Getter : 클래스의 모든 필드에 대한 getter 메서드를 자동으로 생성해준다, 조회 할수 있게
    • @AllArgsConstructor : 클래스의 모든 필드를 매게변수로 받는 전체 생성자를 자동 생성
    • @NoArgsConstructor : 매게변수가 없는 기본 생성자를 생성한다. accessLevel을 통해 접근 수준을 설정 
@Entity
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor( access = AccessLevel.PROTECTED)
public class Post {

    @Id
    @GeneratedValue
    private Long postId;
    private String title;
    private String content;
}

 

4. JPA Repository 생성

  • JpaRepository를 extends 한 PostRepository interface이다.
  • Spring Data JPA는 JPA의 구현체인 Hibernate를 이용하기 위한 여러 API를 제공
  • Repository는 JpaRepository를 상속 작업을 해준다.
  • JpaRepository의 제네릭 타입으로는 <Entity, PK의 타입>을 지정해고 JPA는 자동으로 스프링의 빈(bean)으로 등록된다
public interface PostRepository extends JpaRepository<Post, Long> {
 // <Post, Long> : Entity, PK의 타입
}

 

5. CRUD 기능 구현하기 

Create 작업
  • save() 메소드를 이용해  Insert작업을 해준다.
    @Transactional
    public CreatePostResponse createPost(CreatePostRequest request){
        Post post = Post.builder()
                .title(request.getTitle())
                .content(request.getContent())
                .build();

        Post savePost = postRepository.save(post);

        return new CreatePostResponse(savePost.getPostId(), savePost.getTitle(), savePost.getContent());
    }

 

 Read 작업
  •  findById() 메소드를 이용해  엔티티의 Id값이 있는지 없는지 체크
    public ReadPostResponse readPostById(Long postId){

        //postId있는지 없는지 체크
        Post foundPost = postRepository.findById(postId)
                    //예외 오류 처리
                    .orElseThrow(() -> new EntityNotFoundException("해당 postId로 조회된 게시글이 없습니다"));

        return new ReadPostResponse(foundPost.getPostId(), foundPost.getTitle(), foundPost.getContent());
    }

 

Update 작업
  •  findById() 메소드를 이용해  엔티티의 Id값이 있는지 없는지 체크
  • Dirty Checking : 상태에 변화가 생긴 것을 검사
    • JPA에서는 트랜잭션이 끝나는 시점에 변화가 있는 모든 엔티티 객체를 데이터베이스에 자동으로 반영
    • 영속성 컨텍스트가 관리하는 엔티티에만적용
    • 참고글 
 public UpdatePostResponse updatePost(Long postId, UpdatePostRequest request){

        // postId있는지 없는지 체크
        Post foundPost = postRepository.findById(postId)
                //예외 오류 처리
                .orElseThrow(() -> new EntityNotFoundException("해당 postId로 조회된 게시글이 없습니다"));

        // Dirty Checking
        // 바꿔온 엔티티를 jps가 감지하고 바꿔줌
        foundPost.update(request.getTitle(), request.getContent());

        return new UpdatePostResponse(foundPost.getPostId(), foundPost.getTitle(), foundPost.getContent());
    }

 

Delete 작업
  •  findById() 메소드를 이용해  엔티티의 Id값이 있는지 없는지 체크후 삭제한다.

 

  @Transactional
    public DeletePostResponse deletePost(Long postId){
        Post foundPost = postRepository.findById(postId)
                .orElseThrow(() -> new EntityNotFoundException("해당 postId로 조회된 게시글이 없습니다"));
        postRepository.delete(foundPost);
        return new DeletePostResponse(foundPost.getPostId());
    }

 

다음엔 Test 작업에 대해 기록해보겠다.

 

Reference :

MySQL & JPA 연동 및 테스트

 

더티 체킹 (Dirty Checking)이란?