Spring Boot/STUDY

[Spring Boot] Spring Boot H2, Oracle, JPA

코맹 2024. 6. 17. 17:16

 

Spring Boot JPA 프로젝트 생성 및 설정

 

 

Spring Boot JPA 프로젝트 생성

더보기
- Spring Boot JPA 프로젝트 생성
  - 명령 팔레트로 시작, Spring Initialzr: Create a Gradle Project ...
  - Spring Boot version -> 3.2.6
  - project language -> Java
  - Group Id -> com.eunji
  - Arifact Id -> backboard
  - packaging type -> Jar
  - java version -> 17
  - Dependency
    1. Spring Boot DevTools
    2. Lombok
    3. Spring Boot Web
    4. Thymeleaf
    5. Oracle Driver(later)
    6. H2 Database(later)
    7. Data JPA(later)
  - Spring03 폴더 내에서 **Generate into this folder**

 

build.gradle 디펜던시 확인

dependencies {
	// 기본 디펜던시
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web-services'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	// 테스트를 위한 디펜던시
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

 

 application.prooerties 기본설정 입력

  • (포트번호, 로그색상, 자동재빌드, 로그레벨)
spring.application.name=backboard

## 포트 설정 8080은 기본
server.port=8080

## 로그 색상
spring.output.ansi.enabled=always

## 수정사항 저정시 자동재빌드
spring.devtools.livereload.enabled=true
spring.devtools.restart.enabled=true

## 로그레벨 설정
logging.level.org.springframework=info
logging.level.com.eunji=debug

 

build.gradle - DB를 위한 디펜던시 추가 (H2, Oracle, JPA)

runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.oracle.database.jdbc:ojdbc11'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

application.properties 추가

## H2 설정 - 내가 개발할 때만 쓰는 형태 추천
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:~/local
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

## JPA 설정
spring.jpa.database=h2
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
### ddl-auto 자동으로 테이블을 만들어주는 기능
### 데이터베이스 관리 정책 >> 실제 운영하는 서버에서는 validate(1), update(2)
### create: application 실행시마다 새로 생성
### create-drop: application 실행시 생성, 종료시 드랍
### update: 최초 한번만, 변경사항이 있으면 반영
### validate: DB테이블과 엔티티 클래스가 일치하는지 검증만
### none(default)
spring.jpa.hibernate.ddl-auto=create

 

 

http://localhost:8080/h2-console 접속

  • DBeaver 역할을 함

  • connect를 눌렀을 때 위 화면이 뜨면 성공!

  • inmemory DB로 서버도 동작할 때만 사용 가능 (더 찾아보기)

 


 

Spring Boot JPA 프로젝트 기능 구현



 

더보기
- Spring Boot JPA 프로젝트 개발시작
  1. (설정) build.gradle 디펜던시 확인
  2. (설정) application.prooerties 기본설정 입력(포트번호, 로그색상, 자동재빌드, 로그레벨)
  3. MVC 패턴에 맞춰서 각 기능별로 폴더를 생성(Controller, service, entity ...)
  4. /controller/MainController.java 생성, 기본 메서드 구현
  5. (설정) application.properties H2, JPA 설정 추가
  6. (설정) 웹 서버 실행 http://localhost:8080/h2-console DB 연결 확인

  7. /entity/Board.java 생성
    - GenerationType 타입
      - AUTO: SpringBoot에서 자동으로 선택(X)
      - IDENTITY: MySQL, SQLServer
      - SEQUENCE: Oracle
    - column 이름을 createDate로 만들면 DB에서 컬럼명 create_date로 생성됨
      - 컬럼명에 언더바(_)를 넣지 않으려면 @column(name="createDate")을 사용해서 변경
  8. /entity/Reply.java 생성
  9. 두 entity 간 @OneToMany, @ManyToOne을 설정
  10. 웹 서버 재시작 후 h2-console에서 생성 확인
  11. /repository/BoardRepository.java 빈 인터페이스(JpaRepository) 생성
  12. /repository/ReplyRepository.java 빈 인터페이스 생성
  13. application.properties ddl-auto-create -> ddl-auto-update로 변경
  14. /test/.../repository/BoardRepositoryTests.java 생성, 테스트 메서드 작성
  15. 테스트 시작

 

Entity 생성

  • com.eunji.spring03.backboard.entity에 Board.java 생성
package com.eunji.backboard.entity;

import java.time.LocalDateTime;

import org.springframework.data.annotation.CreatedDate;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

// 게시판 보드 테이블 엔티티
@Getter
@Setter
@Entity             // 테이블화
@Builder            // 객체 생성을 간략화
@NoArgsConstructor  // 파라미터 없는 기본 생성자 자동생성
@AllArgsConstructor // 멤버변수 모두를 파라미터로 가지는 생성자 자동생성
public class Board {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE)   // 나중에 Oracle로 바꾸겠다는 의미
  private Long bno;                   // PK

  @Column(name = "title", length = 250)
  private String title;               // 글 제목

  @Column(name = "content")
  private String content;             // 글 내용

  @CreatedDate
  @Column(updatable = false)   // updatable = false : 작성날짜 바꾸지 않겠다는 의미
  private LocalDateTime createDate;   // 글 생성일

}
  • @id => pk 라는 의미

 

  • com.eunji.spring03.backboard.entity에 Reply.java 생성
package com.eunji.backboard.entity;

import java.time.LocalDateTime;

import org.springframework.data.annotation.CreatedDate;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Reply {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE)
  private Long rno;

  @Column(name = "content", length = 1000)
  private String content;

  @CreatedDate
  @Column(name = "createDate", updatable = false)     
  private LocalDateTime createDate;   // 글 생성일

  // 중요, ERD로 DB를 설계하지 않고 엔티티 클래스로 관계를 형성하려면 반드시 사용해야 한다.
  // RelationShip 다대일 설정
  @ManyToOne    // 1:다의 관계(보드가 1, 댓글이 다)
  private Board board;
  
}

  • h2 database에서 BOARD, REPLY 테이블이 생성된 것을 확인할 수 있다.

repository 생성

  • com.eunji.spring03.backboard.repository BoardRepository.java와 ReplyRepository.java 인터페이스 생성
package com.eunji.backboard.repository;

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

import com.eunji.backboard.entity.Board;

@Repository
public interface BoardRepository extends JpaRepository<Board, Long>{
  
}
package com.eunji.backboard.repository;

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

import com.eunji.backboard.entity.Reply;

@Repository
public interface ReplyRepository extends JpaRepository<Reply, Long>{
  
}

 

 

test 실행

  • /test/.../repository BoardRepositoryTests.java 생성, 메서드 작성
package com.eunji.backboard.repository;

import java.time.LocalDateTime;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.eunji.backboard.entity.Board;

@SpringBootTest
public class BoardRepositoryTests {
  // JUnit 테스트
  @Autowired
  private BoardRepository boardRepository;

  @Test
  void testInsertBoard() {
    Board board1 = new Board();   // 전통적인 객체 생성방식
    board1.setTitle("첫번째 테스트입니다.");
    board1.setContent("내용입니다.");
    board1.setCreateDate(LocalDateTime.now());
    this.boardRepository.save(board1);

    // Builder를 사용한 객체 생성 방식
    Board board2 = Board.builder().title("두번째 테스트입니다.")
                                  .content("내용입니다.")
                                  .createDate(LocalDateTime.now()).build();
    this.boardRepository.save(board2);
    System.out.println("테스트 완료!!");

  }
  
}

 

테스트 실행 전 application.properties에서

spring.jpa.hibernate.ddl-auto=create -> spring.jpa.hibernate.ddl-auto=update 변경

 

  •  테스트가 완료된 것을 확인할 수 있음

 

 

테스트 완료된 것 확인하고 나서 디버그 실행

  • 디버그 실행 후 H2 Database에서 select * from board 쿼리문을 통해 데이터가 insert 된 것을 확인할 수 있음