JPA는 DB에 쿼리를 자동적으로 DB방언에 맞춰서 만들어 주는 매우 편리한 기능을 제공한다. 그렇기 때문에, 개발자들은, 서비스 로직에 대한 부분에 집중을 할 수 있으며, 반복적인 코드에 대한 소비를 줄 일 수 있다. 

이러한 JPA와 객체를 매핑시키는 작업을 어노테이션으로 간단하게 할 수 있다.

 

1. 엔티티 매핑에 대해서 소개(Entity Mapping)

 

@Entity 

@Entity
public class Member {
	private Long id;
	private String username;
}

→ 이 엔티티(테이블)는 JPA가 직접 관리한다라는 의미로 밑에 있는 id, username의 객체와 테이블이 매핑된 것이다.          즉, Member class는 JPA가 관리하는 Entity다.

※ 필수 조건으로 반드시 기본 생성자가 존재해야 된다. 또한, final, enum, interface, inner클래스에서 사용할 수없다.

 

@Entity(name = " ")

name =""를 사용하면 JPA에서 사용할 Entity 이름을 지정할 수 있지만, 기본값이 클래스 이름 그대로이기 때문에, 가급적 기본값으로 사용을 한다.

 


 

 

2. 데이터베이스 스키마 자동 생성(Database Schema)

@Entity
public class Member {
	private Long id;
	private String username;
	private String address; //새로 추가update
	prvate String age; // 매핑이 되었는지 확인 validate
}
<properties>
	<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

	<property name="hibernate.hbm2ddl.auto" value="?" />
</properties>

persistence.xml에서 h2데이터베이스로 데이터 베이스 방언을 설정하고, hibernate가 데이터 베이스 방언으로 적절한 스키마를 생성해준다라는 의미이다.

 

value="org.hibernate.dialect.(H2 Dialect)에서 (?) 안을 다른 데이터베이스로 설정할 수 있다. 

 

property name="hibernate.hbm2ddl.auto" value="?"의 value안에 create, create-drop , update, validate, none를 넣어 스키마를 자동생성 방식을 정할 수 있다.

  • create의 경우기존 테이블을 삭제 후 다시 생성해 준다. 즉, 애플리케이션을 재가동시 전에 저장되었던, 모든 테이블이 드롭(삭제)되고, 다시 생성되므로 id값이 1부터 시작된다.
  • create-drop의 경우 create와 같으나, 종료 시점에 테이블을 drop(삭제)한다.
  • update의 경우 변경되는 부분만 반영된다. 위의 Entity 테이블을 보면, address가 새로 추가하고 싶은데, 테이블을 드롭(삭제)하고 싶지 않을 경우 사용한다. (삭제로 인한 update는 불가)
  • validate의 경우는 Entity와 테이블이 정상 맵핑 되어 있는지 확인해 준다. age를 추가했는데, 테이블에 정상적으로 들어가 있는지 확인할 때
  • none는 뜻그대로, 사용하지 않는다라는 의미이다.

※ 하지만, 운영단계에서 운영서버에서는 절대로 create, create-drop, update를 사용하면 안 된다. 몇천만명의 유저 정보가 있는 테이블이 drop 되고, update로 인해 몇 분간 서비스(시스템)가 중단된다고 생각해보자. 해결할 때 까지 죽어보자..

 


3. 필드와 칼럼 매핑

@Entity 
public class Member { 
 	@Id 
 	private Long id; 
    
 	@Column(name = "name") 
 	private String username; 
    
 	private Integer age; 
    
 	@Enumerated(EnumType.STRING) 
 	private RoleType roleType; 
    
 	@Temporal(TemporalType.TIMESTAMP) 
 	private Date createdDate; 
    
 	@Temporal(TemporalType.TIMESTAMP) 
 	private Date lastModifiedDate; 
    
 	@Lob 
 	private String description; 
 
 	pubilc Member(){
    } //@Entity로 인한 기본생성자 -> @Nooargsconstructor으로 대체 가능
}

(1) @id = id임을 알려준다

 

(2) @Column(name, nullable, length 등등) =  칼럼의 이름, null값 허용 조건, 문자 길이 제약조건 등을 지정할 수 있다.

 

(3) @Enumerated(EnumType.STRING) = enum값 매핑을 할 때 사용한다. 속성의 기본값이 ORDINAL로 되어 있지만, STRING으로 바꾸어 줘야 한다. 그 이유는, 데이터 베이스에 보면, roleType이 숫자로 들어와 있기 때문이다.

username1의 RoleType(RoleType.USER) -> 데이터베이스에 RoleType = 0으로 저장된다. 

username2의 RoleType(RoleType.ADMIN) -> 데이터베이스에 RoleType= 1으로 저장된다. 

하지만, 여기에 GUEST라는 RoleType가 추가된다면

 

밑에 예제를 보자

public enum RoleType{
	USER, ADMIN // -> STUDENT가 추가
    STUDENT, USER, ADMIN
}

STUDENT의 추가로 

username1의 RoleType(RoleType.USER) -> 데이터베이스에 RoleType = 0

username2의 RoleType(RoleType.ADMIN) -> 데이터베이스에 RoleType = 1

username3의 RoleType(RoleType.STUDENT) -> 데이터베이스에 RoleType = 0

으로 010 다시 0부터 시작한다. 예를 들어 0부터 시작하여 1, 2, 3, 4, 5, 6~... 14576849에서 -> 0으로 다시 시작되면 해결할 때까지 죽어야되는 버그가 발생하기 때문에, 꼭 STRING으로 하자 Stirng으로 한다면, USER, ADMIN, STUDENT로 데이터베이스에 저장된다.

 

(4) @Temporal = TemporalType.DATE: 날짜, 데이터베이스 date 타입과 매핑 (예: 2022–04–22) 

                       TemporalType.TIME: 시간, 데이터베이스 time 타입과 매핑 (예: 12:48:44)

                      TemporalType.TIMESTAMP: 날짜와 시간, timestamp 타입과 매핑(예: 2022–04–22 12:48:44)

날짜, 시간을 나타낼 수 있다.

 

(5) @Lob = 지정할 수 있는 속성이 없다. 엄청 큰 데이터를 넣을 때 사용된다.

 

(6) @Transient = 매핑을 하고 싶지 않을 때 사용된다. 데이터베이스에 저장되지 않는다.

 

 

※ 많이 부족한 초보 개발자 입니다. 혼내주세요 배우겠습니다. 

'Back-end > Spring' 카테고리의 다른 글

@NoArgsConstructor,@RequiredArgsConstructor,@AllArgsConstructor  (0) 2021.09.11
@Builder  (0) 2021.09.08
@Getter, @Setter  (0) 2021.09.07

이 3가지는 생성자를 자동으로 생성해주는 어노테이션이다.

 

@NoArgsConstructor : 파라미터가 없는 생성자를 생성한다.

주의 : 

1. 필드들이 final로 생성되어 있는 경우에는 필드를 초기화 할 수 없기 떄문에, 생성자를 만들 수 없다.

@NoArgsConstructor(force = true)옵션을 이용해서 final필드를 0,false,null등으로 초기화를 강제로 시켜 만들 수 있다.

2. @NonNull같이 필드에 제약조건이 설정되어 있는 경우, 생성자내 null-check로직이 생성되지 않는다.

 

@RequiredArgsConstructor : 추가 작업을 필요로 하는 필드에 대한 생성장를 생성하는 어노테이션이다.

초기화 되지 않은 모든final필드, @NonNull이 적용되어 있는 모든 필드에 자동적으로 생성자를 생성해 준다.

@NonNull로 마크돼있는 필드들은 null-check가 추가적으로 생성되며, @NonNull이 마크되어 있지만, 파라미터에서 null값이 들어온다면 생성자에서 NullPointerException이 발생한다.

파라미터의 순서는 클래스에 있는 필드 순서에 맞춰서 생성해야 된다.

 

@AllArgsConstructor : 클래스에 존내하는 모든 필드에 대한 생성자를 자동으로 생성해준다.

만약 필드중에서 @NonNull 애노테이션이 마크되어 있다면 생성자 내에서 null-check 로직을 자동적으로 생성한다.

 

 

생성자 관련 애노테이션을 사용할 때 주의사항

 

1. static 필드들은 스킵

 

2. 파라미터의 순서는 클래스에 있는 필드 순서에 맞춰서 생성하기 때문에 매우 주의.

 

→ 만약 클래스 필드의 순서를 바꾸었을 때 롬복이 자동적으로 생성자 파라미터 순서를 바꾸어 주기 때문에 주의하지 않으면 버그가 발생할 수 있다.

 

3. AccessLevel을 꼭 설정.

 

→ 세 애노테이션 모두 접근 제한자를 AccessLevel로 설정할 수 있다.

 

기본값은 public이지만 필요로 따라서 접근제한자를 설정해줘야 한다.

'Back-end > Spring' 카테고리의 다른 글

Entity Mapping(엔티티 매핑)  (0) 2022.04.22
@Builder  (0) 2021.09.08
@Getter, @Setter  (0) 2021.09.07

JAVA에는 객체를 생성할 때 사용하는 패턴이 여러가지가 있다. 그 중에서 Builder pattern는 어느 필드에 어떤 값을 채워야 할지 명확하게 지정할 수 있어, 코드가 명시적이다.

[Builder Pattern 의 장점]

1. 필요한 데이터만 설정 가능

2. 가독성을 높일 수 있음

3. 유연성을 확보 가능

4. 불변성을 확보 가능

 

객체를 생성하는 대부분의 경우에는 빌더 패턴을 적용하는 것이 좋다. 물론 예외적인 케이스로 엔티티(Entity) 객체 또는 도메인(Domain) 객체로부터 DTO를 생성하는 경우라면 직접 빌더를 만들고 하는 작업이 번거로우므로 Model Mapper와 같은 라이브러리를 통해 생성을 위임할 수 있다.

 

'Back-end > Spring' 카테고리의 다른 글

Entity Mapping(엔티티 매핑)  (0) 2022.04.22
@NoArgsConstructor,@RequiredArgsConstructor,@AllArgsConstructor  (0) 2021.09.11
@Getter, @Setter  (0) 2021.09.07

객체 지향 프로그래밍인 JAVA에서 객체의 데이터는 개체 외부에서 직접적으로 접근하는 것을 막는다.

외부에서 데이터를 읽고 변경할 수 있으면 객체의 무결성이 없어지기 때문이다.

 

@Getter

어노테이션 Getter는, 객체 외부에서 객체의 데이터를 읽을 때 사용되는 어노테이션이다.

@Setter

어노테이션 Setter는, 객체 외부에서 객체의 데이터를 변경시 사용되는 어노테이션이다. 

 

 

'Back-end > Spring' 카테고리의 다른 글

Entity Mapping(엔티티 매핑)  (0) 2022.04.22
@NoArgsConstructor,@RequiredArgsConstructor,@AllArgsConstructor  (0) 2021.09.11
@Builder  (0) 2021.09.08

+ Recent posts