본문 바로가기

SpringBoot/Blog프로젝트 with JPA &데어프로그래밍님

21.1.1 TIL - JPA를 이용해서 데이터베이스 테이블 생성하기

21년 새해 첫 날 TIL 포스팅!

게을러져서 매일 하지 못했는데 새해에는 마음 다시 다잡고 목표한대로 강의 끝내고 혼자서 새로 프로젝트도 한번 만들고 할 수 있길!

나도, 그리고 다른 모든 사람들도 새해복 많이받길!!!!

 

※본 포스팅은 데어프로그래밍님 스프링부트 블로그 프로젝트 강의 수강 후 작성한 내용입니다.

 

오늘은 데이터베이스 테이블 생성하기!

해당 프로젝트에서는 User, Board, Reply(대댓글은 없음) 테이블을 생성해서 사용할 예정이다.

테이블 생성을 위해 com.cos.blog에 새로운 package com.cos.blog.model을 생성한다. 여기에 table생성을 위한 모델들이 만들어 질 것 이다.

먼저 User table을 만들어보자!

com.cos.blog.model에 User class를 생성한다.

User class code는 다음과 같다

 

package com.cos.blog.model;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

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

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
  
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity 
public class User {
	
	@Id 
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private int id; 
	
	@Column(nullable = false, length=30) 
	private String username; 
	
	@Column(nullable = false, length=100) 
	private String password;
	
	@Column(nullable = false, length=50) 
	private String email;
	
	@ColumnDefault("'user'") 
	private String role;
	
	@CreationTimestamp 
	private Timestamp createDate; 
	
}

 

우선 @Entity부터 아래로 순서대로 살펴보자.

@Entity는 프로젝트가 실행될 때 user class를 읽어서 자동으로 MySQL에 테이블이 생성되도록 해준다.

 해당 클래스가 orm이다(데이터베이스에 매핑시켜주는 클래스이다) 라는 의미.

 

@Id는 id가 primary key임을 알려주는 것이다.

@GeneratedValue(strategy = GenerationType.IDENTITY)는 id의 넘버링 전략을 정의한 것이다.

옵션의 IDENTITY로 정의하면 프로젝트에서 연결된 데이터베이스의 넘버링 전략을 따라간다는 의미이다. 

예를들어 Oracle을 사용할 경우 시퀀스, MySQL을 사용할 경우 auto_increment 전략을 사용한다.

넘버링 전략 관련해서 application.yaml에서 설명할 내용이 추가로 있는데 이는 모아서 아래서 한번에 적어보려고 한다.

(아래서 작성하려고 했지만 내용도 많고 뭔가 이상하니까 새로 포스트 작성할 것이다!)

id를 정의할 때 int type으로 정의했는데 Long type으로 정의해도 된다. 해당 프로젝트에서는 user의 수가 많지 않기 때문에 int로 정의하였다.

 

@Column(nullable = false, length=30) 은 username은 null이 될 수 없고, username의 최대 length가 30임을 정의해준것이다.

 

@ColumnDefault("'user'") 는 column을 만들 때 role의 default는 'user'임을 정의해준것이다. 이때 큰따옴표 안에 작은따옴표를 사용함으로써 user 가 string임을 알려줘야한다.

지금은 role의 type을 String으로 했지만 Enum으로 사용해주는 것이 더 좋다. role은 admin, user, manager 중 하나로 권한을 부여해주는 것이다. 즉, role에 들어갈 수 있는 것의 범위가 정해져있다. Enum은 도메인(사용할 수 있는 범위)를 지정해주기 때문에 혹시라도 role에 오타로 managerrr와 같이 잘못된 것이 들어가는 것을 방지할 수 있다.

 

@CreationTimestamp는 table이 insert될 때 시간이 자동으로 입력된다.

type을 Timestamp로 정의했는데 java.sql이 가지고있는 Timestamp로 정의해준다.

 

 

Board(게시판) class code

package com.cos.blog.model;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;

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

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
  
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity 
public class Board {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	
	@Column(nullable = false, length=100)
	private String title;
	
	@Lob 
	private String content;

	@ColumnDefault("0") 
	private int count;
	
	@ManyToOne 
	@JoinColumn(name="userId")
	private User user; 
	
	@CreationTimestamp
	private Timestamp createDate;
}

@Lob는 대용량 데이터를 다룰 때 사용한다. 해당 어노테이션을 달면 데이터베이스에 저장될 때 longtext type으로 저장된다.

 

count의 default값을 지정할 때는 int type이기 때문에 큰따옴표만 사용한다.

 

@ManyToOne 은 연관관계를 매핑시켜주는것이다. 한명의 user는 여러개의 게시글을 작성하므로 board가 many, user가 one이 된다.

@JoinColumn(name="userId") 를 하면 Board table에 foreign key가 저장될 때 이름이 userId라고 지정해 준 것이다.

데이터베이스는 오브젝트를 저장할 수 없고, 자바는 오브젝트를 저장할 수 있다. 이 부분에서 충돌이 일어나기 때문에 원래 자바에서는 데이터베이스의 자료형에 맞춰서 저장된다. 따라서 일반적으로 자바프로젝트 였다면 private int user; 로 만들고 쿼리문 사용해서 연결시켜줬겠지만 우리는 JPA(orm)을 사용하기 때문에 object를 그대로 사용할 수 있다.

 

Reply table에는 추가적인 설명이 필요없기 때문에 코드 일부분만 첨부한다.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity //user class가 자동으로 mysql에 테이블이 생성된다. Board라는 클래스는 orm이다(데이터베이스에 매핑시켜주는 클래스이다) 라는 의미
public class Reply {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	
	@Column(nullable = false, length = 200)
	private String content;
	
	@ManyToOne //하나의 게시글에 여러개의 답변
	@JoinColumn(name = "boardId") //foreignkey 이름
	private Board board;
	
	@ManyToOne //여러개의 답변을 하나의 유저가 작성
	@JoinColumn(name = "userId")
	private User user;
	
	@CreationTimestamp
	private Timestamp createDate;
}
댓글