Digking's cave

My First Blog Project (5) : 테이블 만들기(User,Board,Reply) / JPA 설정 / JPA 연관관계매핑 /양방향매핑 본문

Spring/My First Blog Project

My First Blog Project (5) : 테이블 만들기(User,Board,Reply) / JPA 설정 / JPA 연관관계매핑 /양방향매핑

디깅 2022. 12. 16. 15:43
728x90

#jpa는 orm 이다

(orm은 java 등 프로그래밍언어의 object를 테이블로 맵핑해준다.)

 

application.yml 설정추가

  jpa:
    open-in-view: true
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
      use-new-id-generator-mappings: false
    show-sql: true
    properties:
      hibernate.format_sql: true

ddl-auto

: create  - table을 새로 생성 (기존에 있어도 새로 생성)

: upgrage - 기존 table에 추가

: none

 

physical-strategy

: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

 - entity를 만들 때 변수명 그대로 DB field에 만들어 준다.

: org.hibernate.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

- caml표기법을 underscore로 변경해서 만들어준다 (myEmail -> my_email)

 

use-new-id-generator-mappings : false

- jpa가 사용하는 기본 넘버링 전략 사용 여부(false = 사용안함)

 

show-sql :true

- console 창에 sql 보여준다

 

hibernate.format_sql:true

- sql문을 정렬해서 보여준다.

 

 

#Model 패키지 생성

User.java

package com.cos.blog.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.DynamicInsert;
import javax.persistence.*;
import java.sql.Timestamp;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false, length = 30, unique = true)
    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

- class를 테이블화 시키기 위해 사용 (class명과 가까이 맨 밑에 두는게 좋다)

- User클래스가 MySQL에 테이블이 생성된다.

 

@Id

- Primary Key가 될 값을 선언

 

@GeneratedValue(strategy = GenerationType.IDENTITY)

- 프로젝트에서 연결된 DB의 넘버링 전략을 따라간다.

우리는 MYSQL이니까 AUTO Increament 사용

 

@Column : column을 맵핑

- nullable : null값 허용 여부

- length : 허용 길이 설정

 

@ColumnDefault

- default 컬럼값 설정

 

@CreateTimestamp

- 자동으로 시간 입력

 

Board.java

package com.cos.blog.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.List;

@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;

    @OneToMany(mappedBy = "board",fetch = FetchType.EAGER)
    private List<Reply> reply;

    //필드이름은 userId로 만들어지고, 연관관게는 manytoone
    //User를 참조하고, 자동으로 FK가 만들어진다
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="userId")
    private User user;

    @CreationTimestamp
    private Timestamp createData;
}

@Lob 

- 대용량 데이터 쓸 때 사용

 

Reply.java

package com.cos.blog.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.sql.Timestamp;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@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;
}

-

DB는 오브젝트를 저장할 수 없기 때문에 FK를 사용한다.

하지만 자바는 ORM을 통해 오브젝트 저장이 가능하다.

JDBC를 사용했을 때와는 다르게 JPA에서는 PK를 멤버변수로 갖지 않고 엔티티 전체를 참조할 수 있다.

 

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

@JoinColumn

- 매핑정보 설정

 

(name="userId")

- 외래 키는 userid ( 생략가능)

 

@ManyToOne

Many=Board, User = One

 

//Reply.java 

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

--> 하나의 게시글에는 여러개의 답글이 달릴 수 있다.

 

    @OneToMany(mappedBy = "board",fetch = FetchType.EAGER)
    private List<Reply> reply;

    //필드이름은 userId로 만들어지고, 연관관게는 manytoone
    //User를 참조하고, 자동으로 FK가 만들어진다
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="userId")
    private User user;

 

mappedBy : 연관관계의 주인이 아니다.(난 FK가 아니에요, DB에 칼럼을 만들지 마세요)

board를 select할 때 필요한 값일 뿐이다.

이 이름은 java 소스에 작성된 필드명으로 가져온다

fetch = FetchType.LAZY 

엄청 많이 가져오니까, 필요하면 가져오고 아니면 안가져올게

fetch = FetchType.EAGER

board정보를 select하면 한 건밖에 없으니 바로 가져올게

 

 

 

반응형