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;
}
}
package shop.mtcoding.bank.domain.user;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum UserEnum {
ADMIN("관리자"), CUSTOMER("고객");
private String value;
}
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으로 바꿔준다.
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로 생성이 된다.
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;
}
}
package shop.mtcoding.bank.domain.transaction;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum TransactionEnum {
WITHDRAW("출금"), DEPOSIT("입금"), TRANSFER("이체"), ALL("입출금내역");
private String value;
}