Mybatis로 데이터베이스를 처음 접했다보니 JPA, Entity.. 등등 모두 익숙치 않은 것 투성이었다.
그래서 Entity란 무엇인지 내가 이해한 것 + 공부한 것 바탕으로 기록을 남겨보고자 한다..!
데이터의 집합을 의미하며 저장되고 관리되어야하는 데이터이다.
실질적으로 DB의 테이블과 매칭된다.
직접적으로 DB와 연결되어있기 때문에 DB와 내용이 다르면 안된다.
회원가입api를 만들면서 작성해본 User Entity를 보며 더 자세히 알아보고자 한다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "USERS")
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
}
@Entity는 DB테이블에 대응하는 하나의 클래스이다.
springboot에게 "이곳은 Entity영역"이라고 알려주는 어노테이션이라고 생각하면 된다.
해당 어노테이션이 붙은 클래스는 JPA가 관리해주며, JPA를 사용해서 DB테이블과 매핑할 클래스는 @Entity를 붙여야만 매핑이 가능하다.
@Entity
public class User {
...중략
@Getter는 엔티티의 필드를 조회할 때 사용하는 어노테이션으로 반드시 필요하다.
@Entity
@Getter
public class User {
...중략
보통은 @Setter와 @Getter가 짝꿍처럼 같이 쓰이는 것이 익숙할 것이다.
그러나, @Getter만 단독으로 사용해준 이유가 있다.
바로, @Setter를 써주면 entity가 변경될 수 있는 위험이 따르기 때문이다.
특히, pk(고유키)의 경우 변경되지 않아야하는 데이터인데 @Setter로 인해 데이터가 변경된다면 어디서 변경되었는 추적하기 힘들어진다.
그래서 @Setter는 사용하지 않고 @Getter만 사용해준다.
@NoArgsConstructor(access = AccessLevel.PROTECTED)는 파라미터가 없는 기본 생성자를 자동으로 생성해주는 어노테이션이다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
...중략
java의 ORM 기술인 JPA는 기본적으로 기본 생성자를 요구한다.
기본생성자가 없으면 에러가 발생한다.
그래서 Entity에는 @NoArgsConstructor 어노테이션을 반드시 붙여주어야 한다.
나아가 (access = AccessLevel.PROTECTED)로 설정해주는 이유는 Proxy와 관련이 있는데, 쉽게 말하면 Entity에 외부 접근을 차단하기위해 PROTECTED를 활용한다고 보면 된다.
@AllArgsConstructor는 클래스의 모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성해주는 어노테이션이다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class User {
...중략
현재 데이터가 변경될 위험이 있어 @Setter는 사용해주지 않고 있다.
또, Step3에서 @NoArgsConstructor( access = AccessLevel.PROTECTED) 로 사용해주었다.
그렇기 때문에 데이터를 넣기 위해서는 빌더 패턴을 사용하게 되는데, 이 빌더가 생성자를 필요로 한다.
@NoArgsConstructor( access = AccessLevel.PROTECTED)를 통해 기본생성자가 만들어졌지만 접근 제한으로 인해 외부에서 생성자에 접근할 수 없다.
그래서 외부에 있는 빌더가 전체 필드를 가진 생성자에 접근할 수 있도록 하기 위해 @AllArgsConstructor 어노테이션을 적어주는 것이다!
@Table(name = "")는 DB의 테이블과 연결시켜주기 위해 사용하는 어노테이션이다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "USERS")
public class User {
...중략
User Entity를 USERS테이블에 매칭시켜주었다.
@Builder는 Lombock의 어노테이션이다.
빌더 패턴을 적용할 객체에 @Builder 어노테이션을 달아주기만 하면 된다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "USERS")
@Builder
public class User {
...중략
이렇게 Entity에 달아주는 어노테이션에 대해 알아봤다.
이제 Entity 안에 어떤 코드들이 입력되는지 간단하게 알아보고 마치겠다.
@Id는 DB의 pk(고유키)를 매칭해주는 어노테이션이다.
id라는 값에 @Id 어노테이션을 붙여줌으로써 id는 해당 DB의 고유키와 매칭된 셈이다.
@GeneratedValue(strategy = GenerationType.IDENTITY)는 기본키 생성을 DB에 위임해주는 어노테이션이다.
sequence를 자동으로 생성해주는 쿼리문을 작성하는 것처럼 해당 어노테이션만 작성해주면 id값이 자동 생성된다.
...중략
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column은 객체 필드를 테이블의 컬럼에 매핑시켜주는 어노테이션이다.
()괄호 안에 해당 컬럼의 제약조건을 입력할 수 있다.
nullable = false, unique = true 처럼 null값이 들어오지 못하게 한다거나, unique키로 지정해서 중복을 제거하는 등의 원하는 제약 조건을 입력해주면 된다.
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
}
Entity에 어떤 어노테이션이 붙게 되는지, 왜 붙는건지, Entity가 데이터와 어떻게 매칭되는지 알아보았다.
스스로 작성해보면서 Entity에 대해 잘 모르고 있던 점도 알게 되었다!
레퍼런스
@Entity
엔티티 어노테이션
@Getter 단독 사용 이유
@NoargsConstructor (access = AccessLevel.PROTECTED)
Builder pattern