본문 바로가기
개발일지_development diary/YSit

YSit [4] - 엔티티 개발하기

by YES_developNewbie 2022. 12. 24.

도메인을 설계했던 내용을 토대로 엔티티 개발을 시작했다.

도메인 패키지를 생성하고 먼저 User 클래스를 생성했다. JPA에게 엔티티임을 알려주기 위해 Entity 어노테이션을 넣고 DB에는 'user'라는 예약어가 있어서 혹시 모를 상황에 대비해 @Table 어노테이션으로 User가 아닌 Users로 테이블을 생성했다. 보통 getter와 setter를 둘다 사용하는 것 같던데 강의에서는 setter 사용을 삼가라는 내용이 있었다. 이유는 이후에 다른 사람이 코드를 보면 어떤 지점에서 데이터 변경이 일어나는지 쉽게 알 수가 없어서 그렇다는 내용이었는데 생각해보니 맞는 말 같아서 이후에 setter 사용을 하지 않기 위해 아예 setter 어노테이션을 사용하지 않고 getter 어노테이션만 세팅해주었다. 설계 때 생각해놓은 컬럼들을 선언해주고 JPA에서 컬럼임을 알 수 있게 @Column 어노테이션을 선언해주었다.

 

식별자이자 PK로 사용할 id는 @Id 어노테이션과 mysql로 치면 auto increment인 @GeneratedValue를 선언해주었다. loginId 컬럼은 유니크해야 하기 때문에 @Column 어노테이션에서 unique를 true로 설정해주었다. loginPw 컬럼은 SHA-256 기법을 사용할 생각이었기 때문에 SHA-256 최대 길이인 64에서 혹시 모를 상황에 +1을 해서 length를 65로 설정해주었다. 그리고 schoolCategory는 enum을 사용해 STUDENT, TEACHER을 알 수 있도록 하기 위해서 @Enumerated를 선언해주었다. @Enumerated를 사용할 때는 주의할 것이 있다. EnumType에는 String과 Ordinal이 있는데, 쉽게 말하면 String은 문자로, Ordinal은 숫자로 값을 저장하는 것이다. 그런데 Ordinal은 한가지 문제점이 있다. 지금 상황을 예시로 들면 STUDENT는 1, TEACHER은 2로 저장하는 것인데, 만약 중간에 값이 하나가 추가가 되어 TEACHER가 3으로 바뀌게 되면 기존에 있던 데이터를 잘못 읽어올 가능성이 높아진다. 그렇기 때문에 값을 문자로서 저장하는 String 타입을 권장하기 때문에 나도 EnumType을 String으로 선언했다.

 

@Id @GeneratedValue
@Column(name = "user_id")
private Long id;
private String name;
@Column(unique = true)
private String loginId;
@Column(length = 65)
private String loginPw;

 

다음으로 게시판을 개발했다. Board로 게시판을 생성해주고 Article로 게시물 테이블을 생성해주었다. 이제부터 다른 테이블과의 연관관계를 JPA에게 알려주어야 한다. 게시물의 시점에서 조인 받아야 하는 테이블은 Board와 User 테이블이다. 그렇기 때문에 연관관계에 따라 어노테이션을 선언해주고 조인 받으면 된다. Board와 User 테이블 둘다 Article 입장에서 M : 1 관계이기 때문에 @ManyToOne 어노테이션을 선언해준다. 여기서 fetch를 LAZY로 설정해주어야한다. 왜냐면 EAGER는 즉시 로딩인데, 즉시 실행되어 예측이 어렵고 어떤 쿼리가 실행되는지 추적하기 어렵기 때문이다. 그런데 ManyToOne과 OneToOne은 LAZY가 아닌 EAGER가 디폴트로 설정되어 있기 때문에 직접 LAZY로 설정해주어야 한다. 그리고 @JoinColumn으로 테이블을 조인 받는다.

 

@ManyToOne(fetch = FetchType.LAZY, targetEntity = Board.class)
@JoinColumn(name = "category")
private Board board;

@ManyToOne(fetch = FetchType.LAZY, targetEntity = User.class)
@JoinColumn(name = "user_id")
private User user;

 

이후에 다른 테이블도 생성해주었으나 똑같은 과정이기 때문에 생략해야겠다. 

 

후기

사실 설계 때 했던 내용을 그대로 쓰는 것뿐이라 쉽게쉽게 했던 것 같다. 오히려 나중에 문제가 되는 부분이 있지 않을까 걱정이 된다. 하지만 지금 보기엔 별 문제가 없어 보이기 때문에 계속 들여다보기만 할 뿐이다.