[Springboot] 5 하이버네이트

김호정's avatar
Aug 14, 2024
[Springboot] 5 하이버네이트
 
 
💡
자바에서는 JDBC를 제일 많이 사용한다. 자바랑 DBMS를 연결하는게 JDBC. 그럼 DBMS 가 HDD에 DB에서 데이터를 찾아와서 응답한다. 수영장 튜브를 예측해서 미리 20개 정도 불어놓는다. 사용이 끝나도 바람을 빼지 않는다. => Datasource 테이블, relation, 엔티티 jdbc는 resultSet이 id, title 를 받기 위해 class를 만들어서 거기에 받는다. 마이바티스는 데이터베이스 프레임워크, 하이버네이트도 데이터베이스 프레임워크다. db와 자바는 다른 세상이다. db에서 가져온다고 자바가 바로 아 그렇구나 할 수 없다. 마이바티스와 하이버네이트는 Om을 해준다. (-> DB Framework는 OM(오브젝트 매핑)을 해준다. 매우 편리하다고 한다)
 
 
 
 

1. 하이버네이트 세팅 (application.properties)

notion image
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.ddl-auto=none
위에 이 둘은 무슨 설정이지 ?
Spring Boot 애플리케이션에서 JPA와 Hibernate를 사용하여 데이터베이스 스키마를 처리하는 방식을 제어하는 설정입니다. 이 설정은 Hibernate가 애플리케이션 시작 시 데이터베이스 스키마를 어떻게 처리할지를 결정합니다.

spring.jpa.hibernate.ddl-auto=create

  • 기능: 애플리케이션이 시작될 때 데이터베이스에 존재하는 모든 테이블을 삭제하고, JPA 엔티티에 기반하여 새로운 테이블과 구조를 생성합니다.
  • 특징:
    • 기존의 데이터베이스 스키마가 완전히 삭제되고, 새롭게 정의된 엔티티에 따라 테이블이 재생성됩니다.
    • 주의: 기존의 모든 데이터가 삭제됩니다.
    • 개발 초기나 테스트 환경에서 자주 사용되며, 데이터베이스 구조를 빠르게 초기화하고 싶을 때 유용합니다.
  • 사용 예시:
    • 애플리케이션을 실행할 때마다 테이블 구조를 새로 정의하고, 모든 데이터를 초기화할 필요가 있는 경우.
    • 새로운 기능 개발 중 데이터 구조가 자주 변경되는 경우.
    • spring.jpa.hibernate.ddl-auto=none

    • 기능: Hibernate가 데이터베이스 스키마에 아무런 작업도 하지 않습니다.
    • 특징:
      • 데이터베이스 스키마 생성, 업데이트, 검증 작업이 전혀 수행되지 않습니다.
      • 데이터베이스 스키마가 미리 정의되어 있거나, 외부 도구로 관리되는 경우에 사용됩니다.
      • 운영 환경이나 이미 설정된 데이터베이스에서 주로 사용됩니다.
    • 사용 예시:
      • 이미 생성된 데이터베이스 스키마를 사용하고, Hibernate가 이를 수정하지 않도록 할 때.
      • 스키마 관리가 애플리케이션 외부에서 이루어지는 경우.

      • 요약 비교:

      • create:
        • 스키마 생성: 애플리케이션 시작 시마다 새로 생성.
        • 기존 데이터: 모두 삭제됨.
        • 사용처: 개발 초기, 테스트 환경.
      • none:
        • 스키마 생성: 아무 작업도 하지 않음.
        • 기존 데이터: 유지.
        • 사용처: 운영 환경, 외부에서 스키마 관리.
        운영 환경에서는 보통 none을 사용하고, 개발 환경이나 테스트 환경에서는 create, update 등을 사용하여 스키마를 관리하는 것이 일반적입니다.

2. Board 엔티티 만들기

notion image
 

3. Board 엔티티 작성하고 실행시키기

 
notion image
package shop.mtcoding.blog.board; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.sql.Timestamp; @Entity // DB에서 조회하면 자동 매핑이됨 @Getter @Setter @Table(name = "board_tb") // 테이블 명 설정해주기 public class Board { @GeneratedValue(strategy = GenerationType.IDENTITY) // Auto_increment 설정. 시퀀스 설정 @Id // PK 설정 private Integer id; private String title; private String content; private Timestamp createdAt; }
그럼 아래와 같이 콘솔에 뜬다.
jpa.show.sql=true 설정해줘서 뜨는거임
notion image
 
데이터 베이스 가서 확인해보면, 카멜 표기법으로 적은 애들은 대문자 부분 앞에 _ 가 설정되어있다.
카멜표기법으로 적은건 자바만 이해할 수 있기때문에 데이터베이스 쪽은 대문자앞에 _ 가 붙게 변경된다.
notion image
notion image
 
생성자에 @Builder 빌더 어노테이션 붙여주면 빌더 패턴을 구현할 수 있다. (롬복 어노테이션 사용)
→ 이렇게 하면 생성자를 사용하는 것보다 편리하다.
 
notion image
 
에러가 나는 이유는 기본생성자가 없기 때문이다
 
? ) 기본 생성자가 필요한 이유는 ?
 
q ) Entity에 default constructor 가 왜 필요한가요?
a ) 하이버네이트가 빈 객체를 만들어서 오브젝트 매핑을 해주기 때문에 필요합니다.
 
 
package shop.mtcoding.blog.board; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.sql.Timestamp; @NoArgsConstructor // 빈 생성자 @Entity // DB에서 조회하면 자동 매핑이됨 @Getter @Setter @Table(name = "board_tb") // 테이블 명 설정해주기 public class Board { @GeneratedValue(strategy = GenerationType.IDENTITY) // Auto_increment 설정. 시퀀스 설정 @Id // PK 설정 private Integer id; private String title; private String content; private Timestamp createdAt; @Builder public Board(Integer id, String title, String content, Timestamp createdAt) { this.id = id; this.title = title; this.content = content; this.createdAt = createdAt; } }
 
데이터베이스에서 테이블 데이터는 자바 세상에서는 이해할 수 없는 타입!
서로 이해못하는 타입끼리는 전송과정에서 자기 타입으로 바꿔야한다.
데이터를 받으면 내가 쓸 수 있는 타입으로 변경한다.
 
마이바티스나 하이버네이트를 쓰면 애들이 타입을 자동으로 옮겨준다.(편리)
→ 큰 박스의 데이터를 작은 박스로 하이버네이트가 다 옮겨준다(⇒ 이게 오브젝트 매핑 이다.)
 
q ) Entity에 default constructor 가 왜 필요한가요?
a ) 하이버네이트가 빈 객체를 만들어서 오브젝트 매핑을 해주기 때문에 필요합니다.
 
하이버네이트(or 마이바티스)가 db랑 스프링 사이에 끼여져 있다.
( >> 프록시 같은 애)
하이버네이트(or 마이바티스)가 db에서 테이블 데이터를 받아서
자바에 테이블 데이터랑 똑같은 자료형이 없는지 어노테이션을 스캔함 ( >> 오브젝트(객체)매핑 )
→ 찾으면 찾은 board 객체를 new 한다! default constructor를 때린다!
여기다가 db에서 조회한걸 하나씩 넣어준다. 근데 만약에 default constructor 가 없다 ?
DB에서 가져온 데이터를 갖다 넣을 수가 없으니 에러를 발생시키는 것!
 
너 내가 DB에서 가져온 데이터 받을려면 default Contructor 만들어 두라고 했지? 한다는 것이다.
notion image
 
이를 해결하기 위해서는
default 생성자를 만들어주거나
@NoArgsConstructor 를 붙여주면 기본 생성자가 만들어져서 에러가 안난다.
notion image
 
// 동작방식만 이해하기!
 
Share article

keepgoing