TIL(Today I Learned)

TIL 51th day

keepgoing 2021. 12. 12. 15:52

Entity class에서 getter와 setter

  • 가급적이면 setter는 public으로 설정하지 않는것이 바람직하다.
    • 객체지향의 캡슐화 원칙
  • 이론적으로 Getter, Setter 모두 제공하지 않고, 꼭 필요한 메서드만 제공하는것이 이상적이지만, 실무에서 Entity 데이터를 조회하는 경우가 너무 많으므로 Getter의 경우 모두 열어두는것이 편리하다. Getter는 단순 조회 기능만 제공하기 때문에 아무런 영향을 주지 않는다. 하지만, Setter를 막 열어두면 가까운 미래에 엔터티가 도대체 왜 변경되었는지 추적하기 점점 힘들어진다.
    • 따라서, 엔터티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공하는것이 좋다.

@GeneratedValue

  • Entity에서 sequenceId를 사용할 수 있게해주는 어노테이션

@Column

  • 객체 필드와 DB 테이블 컬럼을 매핑한다
    • name : 매핑할 테이블의 컬럼 이름을 지정

@Embeddable

  • @Embeddable로 지정한 클래스를 밸류클래스라고한다.
  • @Embeddable로 설정한 클래스는 다른 엔터티의 일부로 저장될 수 있음을 설정하는 어노테이션이다.
  • @Embeddable 매핑한 대상은 기본적으로 엔터티 접근 방법을 따른다(필드 접근타입 또는 프로퍼티 접근 타입)
    • 엔터티에서 프로퍼티 접근 타입을 사용한다면(getter/setter) @Embeddable 매핑한 밸류 클래스 역시 프로퍼티 접근 타입을 사용하기 때문에 getter/setter 메소드를 정의해야한다.(lombok은 어노테이션으로 getter/setter 설정)
  • 엔터티에서 @Embeddable 매핑한 밸류클래스를 호출할 때 코드는 아래 코드와 같다.
//Member.java

@Embedded
private Address address;

value클래스

  • 여러개의 값을 하지지만 개념적으로 하나의 값(주소)로 표현합니다.
  • 아래 코드는 예시
class Address{
String address1;
String address1;
String zipCode;
}

Entity of JPA

JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 붙인다. @Entity가 붙은 클래스는 JPA가 관리하는 것으로 엔티티라 부른다

속성

  • name : JPA와 사용할 엔티티 이름을 지정, 사용하지 않을 경우 클래스 이름이 그대로 적용

주의사항

  • 기본생성자 필수
  • final, enum, interface, inner 클래스는 사용할 수 없음
  • 저장할 필드에 final 사용할 수 없음

자바에서는 기본 생성자가 없을 경우 자동으로 생성해주지만 만약 파라미터가 있는 생성자가 클래스에 존재할 경우 기본 생성자를 자동으로 생성해주지 않기 때문에 직접 작성해줘야한다.

@Table

@Table은 엔티티와 매핑할 테이블을 지정하고, 생략시 매핑한 엔티티 이름을 테이블 이름으로 사용한다.

속성

  • name : 매핑할 테이블 이름

JPA 엔티티 매핑

JPA를 사용할 때 엔티티와 테이블을 정확하게 매핑하는 것이 가장 중요하다. JPA는 매핑 어노테이션을 지원하는데 아래와 같이 크게 4가지로 분류할 수 있다.

* 객체와 테이블 매핑
* 기본키 매핑
* 필드와 컬럼 매핑
* 연관관계 매핑

JPA 양방향 관계에서 주인관계 설정

  • (보통 다이면서 외래키(ForignKey)를 주인관계로 설정)
  • 아래는 주인관계 설정 코드
//Member.java
//Order 클래스안에 member 필드에 매핑되었음을 선언(읽기 전용이 된다.), 여기에 값을 넣어도 forignkey 값이 변하지 않는다
    @OneToMany(mappedBy = "member")    
    private List<Order> orders = new ArrayList<>();

LocalDateTime

과거에는 LocalDate 선언후 관련 어노테이션을 설정해줘야 했지만, 자바8부터 hibernate가 자동으로 지원해준다.


@Inheritance

  • Join
    • 세심하게 상속 엔터티를 관리
  • SINGLE_TABLE
    • 한곳에 상속 엔터티를 몰아서 관리

DiscriminatorColumn, DiscriminatorValue

싱글테이블은 상속받는 엔티티들을 구별해야하기 때문에 @Discriminator를 선언해줘야한다


Enum

Enum 선언시 해당 지역변수에 @Enumerated(EnumType.STRING) 선언해줘야하는데, ORDINAL으로 선언하지 말고 STRING으로 선언하는것이 오류방지에 좋다.


1대1 관계에서 외래키 설정

주 Access 엔티티에 ForignKey를 설정하는것이 바람직하다.


관계형 DB에서 다대다 관계

  • 객체는 컬렉션이 존재해서 매핑을 안해도되지만 관계형 DB는 컬렉션 관계를 양쪽에서 가질 수 없기 때문에 일대다, 다대일로 풀어내는 중간 테이블이 필요하다.
    • 하지만 실무에서는 사용하지않는것이 좋다.(필드를 추가하는것이 불가능하기 때문)
  • 아래 코드는 jpa가 제공하는 기능을 확인차 작성하였다.
//category

    @ManyToMany
    //매핑 테이블 생성
    @JoinTable(name = "category_item",    
            joinColumns = @JoinColumn(name = "category_id"),
            inverseJoinColumns = @JoinColumn(name = "item_id")) // 다대일, 일대다 joincolumn을 생성한것.
    private List<Item> items = new ArrayList<>();

Java Reflection

JPA 구현 라이브러리가 객체를 생성할 때 리플랙션 같은 기술을 사용할 수 있도록 기본 생성자를 만들고 protected로 설정하는것이 안전하다.