[스프링부트 나만의 블로그 만들기] 03. 데이터베이스 세팅

이경민·2022년 9월 6일
0

spring

목록 보기
12/20

model 코드

Model 객체는 컨트롤러에서 데이터를 생성해 이를 View에 전달하는 역할을 합니다. Spring에서 Controller의 메서드를 작성할 때는 특별하게 Model이라는 타입을 파라미터로 지정 가능하다.

User 테이블

package com.example.goormblog.model;

import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.sql.Timestamp;

// Entity 어노테이션은 자동으로 mysql에 테이블 생성
@Data
@AllArgsConstructor
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@Table(name="user")
@Entity
public class User {

    @Id                // primary key라는 것을 알려주는 annotation
    @GeneratedValue(strategy= GenerationType.IDENTITY)    // 프로젝트에 연결된 DB의 numbering 전략을 따른다.
    private int id;    // 시퀀스, auto_increment

    @Column(nullable = false, length = 100, unique = true)
    private String username;

    @Column(nullable=false, length=100)
    private String password;

    @Column(nullable=false, length=50)
    private String email;

    @CreationTimestamp      // 시간이 자동 입력
    private Timestamp createDate;
}

코드 작성 시 주의사항

  • CreationTimestamp 어노테이션 사용 시 "java.sql.Timestamp" import하기
  • Id 어노테이션: Key 지정
  • Entity 어노테이션: 자동으로 mysql에 테이블 생성

Reply 테이블

import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.sql.Timestamp;


@Data
@AllArgsConstructor
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@Table(name="reply")
@Entity
public class Reply {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false, length=200)
    private String content;

    @ManyToOne
    @JoinColumn(name="boardId")
    private Board board;

    @ManyToOne
    @JoinColumn(name="userId")
    private User user;

    @CreationTimestamp
    private Timestamp createDate;
}

JoinColumn 어노테이션 사용법

조인 컬럼은 외래 키를 매핑할 때 사용한다.

  • name 속성: 매핑할 외래 키 이름을 지정
  • 특징: 생략 가능하며 테이블들간 연관관계를 설정해 줄때 일대다(1:N) 관계일때 사용

ManyToOne과 OneToMany

  • @ManyToOne: N:1 관계를 표현하는 어노테이션으로 @ManyToOne이 붙은 엔티티가 M이고 반대 엔티티가 1일 때 붙인다.
  • 부모 Entity 에서는 @OneToMany, 자식 Entity 에서는 @ManyToOne 이 된다.

mappedBy

  • 두개의 연관관계중 하나를 고르게 하기 위해 mappedBy를 설정
  • mappedBy가 없는 엔티티가 연관관계의 주인이다.
  • mappedBy가 없는 Entity에 외래키가 생성된다.

Board 테이블

Board에 join된 user는 1개이지만 reply는 1개 이상일 수 있다.

import lombok.*;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.List;


@Data
@AllArgsConstructor
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@Table(name="board")
@Entity
public class Board {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)   // auto_increment
    private int id;

    @Column(nullable=false, length=100)
    private String title;

    @Lob                      // 대용량 데이터
    private String content;   // 썸머노트 라이브러리 <html> 태그가 섞여서 디자인이 됨

    @ColumnDefault("0")
    private int count;        // 조회수

    // fetch = FetchType.EAGER: Board를 select하면 User 정보는 바로 갖고온다.
    @ManyToOne(fetch = FetchType.EAGER)    // Many = Board, User = One
    @JoinColumn(name="userId")
    private User user;                     // DB는 오브젝트 저장 불가. FK, 자바는 오브젝트 저장 가능

    @CreationTimestamp
    private Timestamp createDate;


    // mappedBy 연관관계의 주인이 아니다. FK가 아니기 때문에 DB에 컬럼을 만들면 안된다.
    // reply 테이블의 board가 FK이다.
    @OneToMany(mappedBy = "board", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)     // 1개의 게시글에 여러개의 답변이 존재 가능
    private List<Reply> reply;

}

코드 설명

@ManyToOne(fetch = FetchType.EAGER)    // Many = Board, User = One
@JoinColumn(name="userId")
private User user;                     // DB는 오브젝트 저장 불가. FK, 자바는 오브젝트 저장 가능
  • Board 테이블을 select하면 User 정보도 동시에 제공한다
  • fetch = FetchType.EAGER: Board를 select하면 User 정보는 바로 갖고온다.
  • fetch = FetchType.LAZY: 항상 해당 정보를 갖고오지는 않아도 상관 없다.
  • fetch 타입을 별도 지정하지 않으면 무조건 모든 내용을 들고 오는 것이 기본값.


DB conncection

MySQL DB와 연결하는 코드

config

model 폴더랑 같은 level에 존재하는 config 폴더 아래 DetabaseConfig.java 파일 생성

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;

@Configuration
public class DetabaseConfig {

    @Bean
    public DataSource dataSource() {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("com.mysql.cj.jdbc.Driver");
        dataSourceBuilder.username("root");
        dataSourceBuilder.password("비번");
        dataSourceBuilder.url("jdbc:mysql://localhost:3306/DB_이름");
        return dataSourceBuilder.build();
    }

}

build.gradle 파일

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.projectlombok:lombok:1.18.22'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	implementation 'mysql:mysql-connector-java'

	// https://ktko.tistory.com/entry/Spring-boot-JPA-Open-JDK-%EC%82%AC%EC%9A%A9%EC%8B%9C-Error-creating-bean-with-name-entityManagerFactory-%ED%95%B4%EA%B2%B0
	implementation group: 'org.javassist', name: 'javassist', version: '3.15.0-GA'

	// https://velog.io/@alswl689/MySQL-JPA-SpringBoot-%EC%97%B0%EB%8F%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8Gradle
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

0개의 댓글