Junit Test Application-5-Entity 설계

jaegeunsong97·2023년 8월 2일
0

Junit Bank Application 깃허브

Junit Bank Application 기록 노션

  • User
package shop.mtcoding.bank.domain.user;

import java.time.LocalDateTime;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor // 스프링이 객체를 생성할 때 빈 생성자로 new 하기 때문!!
@Getter
@EntityListeners(AuditingEntityListener.class) // createAt 작동 시킴
@Table(name = "user_tb")
@Entity
public class User {

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
     @Column(unique = true, nullable = false, length = 20)
     private String username;
     @Column(nullable = false, length = 60) // BCryt 인코딩 시
     private String password;
     @Column(nullable = false, length = 20)
     private String email;
     @Column(nullable = false, length = 20)
     private String fullname;
     @Enumerated(EnumType.STRING) // 문자로 변환
     @Column(nullable = false)
     private UserEnum role; // ADMIN, CUSTOMER

     @CreatedDate // Insert시, 자동 추가
     @Column(nullable = false)
     private LocalDateTime createAt;
     @LastModifiedDate // Insert 그리고 Update시, 자동추가
     @Column(nullable = false)
     private LocalDateTime updateAt;

     @Builder
     public User(Long id, String username, String password, String email, String fullname, UserEnum role,
               LocalDateTime createAt, LocalDateTime updateAt) {
          this.id = id;
          this.username = username;
          this.password = password;
          this.email = email;
          this.fullname = fullname;
          this.role = role;
          this.createAt = createAt;
          this.updateAt = updateAt;
     }
}
  • UserEnum
package shop.mtcoding.bank.domain.user;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum UserEnum {

     ADMIN("관리자"), CUSTOMER("고객");

     private String value;
}
  • BankApplication
package shop.mtcoding.bank;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing // 여기
@SpringBootApplication
public class BankApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(BankApplication.class, args);

	}
}

@EntityListeners(AuditingEntityListener.class)가 있어야 밑에 붙인 createAt, updateAt 이 자동으로 insert, update가 된다. 추가로 BankApplication에다가 @EnableJpaAuditing를 꼭 추가해줘야 한다. 한 쌍으로 움직인다.

Entity에 시간을 상속받아서 사용하면 JunitTest시 매우 불편해진다.

@Builder가 있어서 @NoArgsConstructor필요하다. 왜냐하면 객체를 생성할 때 빈 생성자로 new를 하기 때문이다.

@Enumerated(EnumType.STRING)가 있어야 Enum 타입을 String으로 바꿔준다.

  • Account
package shop.mtcoding.bank.domain.account;

import java.time.LocalDateTime;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shop.mtcoding.bank.domain.user.User;

@NoArgsConstructor
@Getter
@EntityListeners(AuditingEntityListener.class)
@Table(name = "account_tb")
@Entity
public class Account {

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
     @Column(unique = true, nullable = false, length = 20)
     private Long number; // 계좌변호
     @Column(nullable = false, length = 4)
     private Long password; // 계좌비번
     @Column(nullable = false)
     private Long balance; // 잔액(기본 1000원)

     @ManyToOne(fetch = FetchType.LAZY) // account.getuser().아무필드호출 -> lazy 발동
     private User user; // fk 주인, user_id로 생성

     @CreatedDate
     @Column(nullable = false)
     private LocalDateTime createAt;
     @LastModifiedDate
     @Column(nullable = false)
     private LocalDateTime updateAt;

     @Builder
     public Account(Long id, Long number, Long password, Long balance, User user, LocalDateTime createAt,
               LocalDateTime updateAt) {
          this.id = id;
          this.number = number;
          this.password = password;
          this.balance = balance;
          this.user = user;
          this.createAt = createAt;
          this.updateAt = updateAt;
     }
}

@ManyToOne의 기본 전략은 EAGER이다. 하지만 여기서는 필요할때 가져오기 위해서 LAZY로 바꾼다. 이 경우 account.getUser().아무필드()호출할때 LAZY 지연로딩이 발동한다. 그리고 User가 Account에 있으므로 fk를 Account가 가지고 있다. 또한 이 fk는 Accoutn 테이블에 생성될 때 user_id로 생성이 된다.

  • Transaction
package shop.mtcoding.bank.domain.transaction;

import java.time.LocalDateTime;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shop.mtcoding.bank.domain.account.Account;

@NoArgsConstructor
@Getter
@EntityListeners(AuditingEntityListener.class)
@Table(name = "transaction_tb")
@Entity
public class Transaction {

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;

     @ManyToOne(fetch = FetchType.LAZY)
     private Account withdrawAccount;
     @ManyToOne(fetch = FetchType.LAZY)
     private Account dipositAccount;

     @Column(nullable = false)
     private Long amount;
     private Long withdrawAccountBalance; // 계좌의 현재잔액과 진짜 잔액의 차이 때문에
     private Long depositAccountBalance;
     @Enumerated(EnumType.STRING)
     @Column(nullable = false)
     private TransactionEnum gubun; // WITHDRAW, DEPOSIT, TRANSFER, ALL
	
     // 계좌의 로그를 남기기위해
     private String sender;
     private String receiver;
     private String tel;

     @CreatedDate
     @Column(nullable = false)
     private LocalDateTime createAt;
     @LastModifiedDate
     @Column(nullable = false)
     private LocalDateTime updateAt;

     @Builder
     public Transaction(Long id, Account withdrawAccount, Account dipositAccount, Long amount,
               Long withdrawAccountBalance, Long depositAccountBalance, TransactionEnum gubun, String sender,
               String receiver, String tel, LocalDateTime createAt, LocalDateTime updateAt) {
          this.id = id;
          this.withdrawAccount = withdrawAccount;
          this.dipositAccount = dipositAccount;
          this.amount = amount;
          this.withdrawAccountBalance = withdrawAccountBalance;
          this.depositAccountBalance = depositAccountBalance;
          this.gubun = gubun;
          this.sender = sender;
          this.receiver = receiver;
          this.tel = tel;
          this.createAt = createAt;
          this.updateAt = updateAt;
     }
}
  • TransactionEnum
package shop.mtcoding.bank.domain.transaction;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum TransactionEnum {

     WITHDRAW("출금"), DEPOSIT("입금"), TRANSFER("이체"), ALL("입출금내역");

     private String value;
}
profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글