본문 바로가기

Springboot

테이블 객체 만들기

실제 데이터베이스 테이블과 매핑되는 Java 객체를 생성하는 방법

 

Entity 코드 정리

Intellij Live Template 사용 추천

-> Settings > Editor > Live Templates

 

User Entity 만들어보기

 - id, username, password 를 가지는 User Entity를 만들면

// User.java
// lombok
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString

// jpa
@Entity
@Table(name = "users")
public class User {

  /**
   * 컬럼 - 연관관계 컬럼을 제외한 컬럼을 정의합니다.
   */
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Long id;

  private String username;

  private String password;

  /**
   * 생성자 - 약속된 형태로만 생성가능하도록 합니다.
   */
  @Builder
  public User(String username, String password) {
    this.username = username;
    this.password = password;
  }

  /**
   * 연관관계 - Foreign Key 값을 따로 컬럼으로 정의하지 않고 연관 관계로 정의합니다.
   */
  @OneToMany
  @Exclude
  private Set<UserChannel> userChannel;

  /**
   * 연관관계 편의 메소드 - 반대쪽에는 연관관계 편의 메소드가 없도록 주의합니다.
   */

  /**
   * 서비스 메소드 - 외부에서 엔티티를 수정할 메소드를 정의합니다. (단일 책임을 가지도록 주의합니다.)
   */
  public void updateUserName(String username) {
    this.username = username;
  }

  public void updatePassword(String password) {
    this.password = password;
  }
}

 

기타 추천 플러그인

Key PromoterX  - 단축키 알림

Presentation Assistant  - 알림 이쁘게 보여주기

 

테이블 객체끼리 관계 만들기

 - 엔티티 간의 관계(일대일, 일대다, 다대다)를 정의하고 매핑하는 방법

 

Raw JPA 연관관계 매핑 기능

 

@OneToOne

- 일대일 관계를 나타내는 매핑 정보

// 일대일 단방향
@Entity
public class Member {
  @Id @GeneratedValue
  @Column(name = "MEMBER_ID")
  private Long id;

  private String username;

  @OneToOne
  @JoinColumn(name = "LOCKER_ID")
  private Locker locker;
}

@Entity
public class Locker {
  @Id @GeneratedValue
  @Column(name = "LOCKER_ID")
  private Long id;

  private String name;
}
// 일대일 양방향
@Entity
public class Member {
  @Id @GeneratedValue
  @Column(name = "MEMBER_ID")
  private Long id;

  private String username;

  @OneToOne
  @JoinColumn(name = "LOCKER_ID")
  private Locker locker;
}

@Entity
public class Locker {
  @Id @GeneratedValue
  @Column(name = "LOCKER_ID")
  private Long id;

  private String name;

  @OneToOne(mappedBy = "locker")
  private Member member;

 

@OneToMany

- 일대다 관계를 나타내는 매핑 정보

- @OneToMany가 단방향으로 쓰이면 문제가 발생할 수 있다

- 속도를 위해 기본적으로 FetchType 설정이 LAZY로 설정되어 있음

- 속성

  •  mappedBy : 연관관계의 주인 필드를 선택한다
  • fetch : 글로벌 페치 전략 설정
  • cascade : 영속성 전이 기능을 사용한다
  • targetEntity : 연관된 엔티티의 타입 정보를 설정한다
// 일대다 단방향 관계
@Entity(name = "parent")
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToMany
		@JoinColumn(name = "parent_id")
    private List<Child> childList;
}

@Entity(name = "child")
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

		@Column(name = "parent_id")
		private Long parentId;
}
// 일대다 양방향 관계는 없음!

// 대신, 다대일 양방향 관계
@Entity(name = "parent")
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToMany(mappedBy="parent")
    private List<Child> childList;
}

@Entity(name = "child")
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

		@ManyToOne
		@JoinColumn(name = "parent_id")
		private Parent parent;
}

 

 

@ManyToOne

- 다대일 관계를 나타내는 매핑 정보

속성

  • optional (default true) : false로 설정하면 연관된 엔티티가 반드시 있어야 함
  • fetch : 글로벌 패치 전략 설정 ( 기본이 EGEAR로 설정되어 있으나 실무에서는 기본 LAZY로 설정하는 것 추천
  • cascade : 영속성 전이 기능 사용
  • targetEntity : 연관된 엔티티의 타입 정보 설정 (targetEntity = Member.class 식으로 사용)

@JoinColumn

  • 외래 키 매핑 시 사용 (Join 을 요청하기 위한 매핑정보로 쓰인다.)
  • @ManyToOne 어노테이션과 주로 함께 쓰인다. (조인대상 컬럼 지정기능을 안쓸거면 생략해도 됨)
  • name 속성은 매핑할 외래키의 이름
  • 어노테이션을 생략해도 외래 키가 생성됨.
    • 생략 시 외래키의 이름이 기본 전략을 활용하여 생성된다.
  • 속성
    • name : 매핑할 외래 키의 이름
    • referencedColumnName : 외래 키가 참조하는 대상 테이블의 컬럼명
    • foreignKey : 외래 키 제약조건 지정 (테이블 생성 시에만 적용됨)
    • unique/nullable/insertable/updateable/columnDefinition/table : @Column의 속성과 같음

@ManyToMany

  • 다대다 관계를 나타내는 매핑 정보(N:M)
  • 다대다 설정을 하게되면 중간 매핑테이블(JoinTable)이 자동으로 생성된다
  • 중간 매핑 테이블은 JPA상에서 숨겨져서(Entity 정의 없이) 관리된다
@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToMany(mappedBy = "parents")
    private List<Child> childs;
}

@Entity
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToMany
    @JoinTable(
        name = "parent_child",
        joinColumns = @JoinColumn(name = "parent_id"),
        inverseJoinColumns = @JoinColumn(name = "child_id")
    )
    private List<Parent> parents;
}
  • 매핑 테이블 관리가 불가능하여서 실무에서는 잘 사용하지 않는 기능 이라고 한다.
    • 실무에서는 매핑 테이블을 아래와 같은 형태로 직접 정의
@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToMany(mappedBy = "parent")
    private List<ParentChild> parentChilds;
}

@Entity
public class ParentChild {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToOne
		@JoinColumn("parent_id")
    private Parent parent;

    @ManyToOne
		@JoinColumn("child_id")
    private Child child;
}

@Entity
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToMany(mappedBy = "child")
    private List<ParentChild> parentChilds;
}

'Springboot' 카테고리의 다른 글

AWS # Identity and Access Management  (0) 2024.07.05
QueryDSL, Auditing, Dynamic Insert/Update  (0) 2024.07.01
쿼리 파일 만들기 (QueryMapper)  (0) 2024.06.28
데이터베이스 연결(Driver)  (0) 2024.06.27
Filter, Intercepter  (0) 2024.06.26