entity 생성

뚜우웅이·2025년 3월 30일

캡스톤 디자인

목록 보기
4/35

User

package com.freemarket.freemarket.user.domain;

import com.freemarket.freemarket.global.auditing.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "users")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long id;

    @Column(updatable = true, nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String name;

    private String phone;

    @Column(nullable = false)
    private boolean enabled = true;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserRole role = UserRole.ROLE_USER;

    @Builder
    public User(String email, String password, String name, String phone, boolean enabled, UserRole role) {
        this.email = email;
        this.password = password;
        this.name = name;
        this.phone = phone;
        this.enabled = enabled;
        this.role = role != null ? role : UserRole.ROLE_USER;
    }

    // 사용자 정보 업데이트
    public void updateProfile(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }

    // 비밀번호 변경
    public void changePassword(String password) {
        this.password = password;
    }

    // 계정 활성화 메서드
    public void activateAccount() {
        this.enabled = true;
    }

    // 계정 비활성화 메서드
    public void deactivateAccount() {
        this.enabled = false;
    }

    // 사용자 역할 변경
    public void changeRole(UserRole role) {
        this.role = role;
    }
}
package com.freemarket.freemarket.user.domain;

public enum UserRole {
    ROLE_USER("일반 사용자"),
    ROLE_SELLER("판매자"),
    ROLE_ADMIN("관리자");

    private final String displayName;

    UserRole(String displayName) {
        this.displayName = displayName;
    }

    public String getDisplayName() {
        return displayName;
    }
}

Review

package com.freemarket.freemarket.review.domain;

import com.freemarket.freemarket.oderItem.domain.OrderItem;
import com.freemarket.freemarket.product.domain.Product;
import com.freemarket.freemarket.user.domain.User;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "review")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Review {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "review_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id", nullable = false)
    private Product product;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_item_id", nullable = false)
    private OrderItem orderItem;

    @Column(nullable = false)
    private int rating;

    @Column(columnDefinition = "TEXT")
    private String content;

    @Builder
    public Review(User user, Product product, OrderItem orderItem, int rating, String content) {
        this.user = user;
        this.product = product;
        this.orderItem = orderItem;
        this.rating = rating;
        this.content = content;
    }

    // 리뷰 내용 업데이트 메서드
    public void update(int rating, String content) {
        this.rating = rating;
        this.content = content;
    }
}

Product

package com.freemarket.freemarket.product.domain;

import com.freemarket.freemarket.global.auditing.BaseEntity;
import com.freemarket.freemarket.user.domain.User;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "products")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "product_id")
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(columnDefinition = "TEXT")
    private String description;

    @Column(nullable = false)
    private long price;

    @Column(nullable = false)
    private int stock;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private ProductCategory category;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private ProductStatus status = ProductStatus.ACTIVE;

    private String imageUrl;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "seller_id")
    private User seller;

    public Product(String name, String description, long price, int stock, ProductCategory category, ProductStatus status, String imageUrl, User seller) {
        this.name = name;
        this.description = description;
        this.price = price;
        this.stock = stock;
        this.category = category;
        this.status = status != null ? status : ProductStatus.ACTIVE;
        this.imageUrl = imageUrl;
        this.seller = seller;
    }

    @Builder


    // 재고 관리 메서드
    public void decreaseStock(int quantity) {
        if (this.stock < quantity) {
            throw new IllegalArgumentException("재고가 부족합니다.");
        }
        this.stock -= quantity;

        // 재고가 0이 되면 품절로 상태 변경
        if (this.stock == 0) {
            this.status = ProductStatus.SOLD_OUT;
        }
    }

    public void increaseStock(int quantity) {
        this.stock += quantity;

        // 재고가 0이 아니면 판매중으로 상태 변경
        if (this.stock > 0 && this.status == ProductStatus.SOLD_OUT) {
            this.status = ProductStatus.ACTIVE;
        }
    }

    // 상품 정보 업데이트
    public void update(String name, String description, long price, int stock, ProductCategory category, String imageUrl) {
        this.name = name;
        this.description = description;
        this.price = price;
        this.stock = stock;
        this.category = category;
        this.imageUrl = imageUrl;

        // 재고 상태에 따라 상품 상태 업데이트
        if (stock > 0 && this.status == ProductStatus.SOLD_OUT) {
            this.status = ProductStatus.ACTIVE;
        } else if (stock == 0 && this.status == ProductStatus.ACTIVE) {
            this.status = ProductStatus.SOLD_OUT;
        }
    }

    // 상품 상태 변경
    public void changeStatus(ProductStatus status) {
        this.status = status;
    }
}
package com.freemarket.freemarket.product.domain;

public enum ProductCategory {
    TEST("테스트");

    private final String displayName;

    ProductCategory(String displayName) {
        this.displayName = displayName;
    }

    public String getDisplayName() {
        return displayName;
    }
}
package com.freemarket.freemarket.product.domain;

public enum ProductStatus {
    ACTIVE("판매중"),
    SOLD_OUT("품절"),
    DISCONTINUED("판매 중단"),
    PENDING("승인 대기");

    private final String displayName;

    ProductStatus(String displayName) {
        this.displayName = displayName;
    }

    public String getDisplayName() {
        return displayName;
    }
}

Order

package com.freemarket.freemarket.order.domain;

import com.freemarket.freemarket.global.auditing.BaseEntity;
import com.freemarket.freemarket.oderItem.domain.OrderItem;
import com.freemarket.freemarket.user.domain.User;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "orders")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "order_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @Column(nullable = false, unique = true)
    private String orderNumber;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private OrderStatus status = OrderStatus.PENDING;

    @Column(nullable = false)
    private long totalPrice;

    @Column(nullable = false)
    private String recipientName;

    @Column(nullable = false)
    private String recipientPhone;

    @Column(nullable = false)
    private String shippingAddress;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<OrderItem> items = new ArrayList<>();

    @Builder
    public Order(User user, OrderStatus status, long totalPrice, String recipientName, String recipientPhone, String shippingAddress, List<OrderItem> items) {
        this.user = user;
        this.status = status != null ? status : OrderStatus.PENDING;
        this.totalPrice = totalPrice;
        this.recipientName = recipientName;
        this.recipientPhone = recipientPhone;
        this.shippingAddress = shippingAddress;
        this.orderNumber = generateOrderNumber();
    }

    private String generateOrderNumber() {
        return "ORD" + System.currentTimeMillis();
    }

    // 주문 아이템 추가 메서 (양방향 관계 관리)
    public void addItem(OrderItem item) {
        items.add(item);
        item.connectToOrder(this);
    }

    // 주문 상태 변경
    public void changeStatus(OrderStatus status) {
        this.status = status;
    }

    // 주문 취소 메서드
    public void cancel() {
        if (this.status == OrderStatus.SHIPPING || this.status == OrderStatus.DELIVERED) {
            throw new IllegalArgumentException("이미 배송중이거나, 배송 완료된 주문은 취소할 수 없습니다.");
        }

        this.status = OrderStatus.CANCELED;

        // 재고 원복
        for (OrderItem item : items) {
            item.cancel();
        }
    }
}
package com.freemarket.freemarket.order.domain;

public enum OrderStatus {
    PENDING("결제 대기"),
    PAID("결제 완료"),
    PREPARING("상품 준비중"),
    SHIPPING("배송중"),
    DELIVERED("배송 완료"),
    CANCELED("주문 취소");

    private final String displayName;

    OrderStatus(String displayName) {
        this.displayName = displayName;
    }

    public String getDisplayName() {
        return displayName;
    }
}

OrderItem

package com.freemarket.freemarket.oderItem.domain;

import com.freemarket.freemarket.global.auditing.BaseTimeEntity;
import com.freemarket.freemarket.order.domain.Order;
import com.freemarket.freemarket.product.domain.Product;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "order_items")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class OrderItem extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "order_item_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id", nullable = false)
    private Order order;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id", nullable = false)
    private Product product;

    // 주문 시점의 상품 정보
    @Column(nullable = false)
    private String productName;

    @Column(nullable = false)
    private int quantity;

    @Column(nullable = false)
    private long price;

    @Builder
    public OrderItem(Order order, Product product, String productName, int quantity, long price) {
        this.order = order;
        this.product = product;
        this.productName = productName;
        this.quantity = quantity;
        this.price = price;
    }

    // 주문 생성 시 상품의 재고 감소
    public static OrderItem createOrderItem(Product product, int quantity) {
        product.decreaseStock(quantity);

        return OrderItem.builder()
                .product(product)
                .productName(product.getName())
                .quantity(quantity)
                .price(product.getPrice() * quantity)
                .build();
    }

    // 주문 취소 시 상품의 재고 원복
    public void cancel() {
        if (this.product != null) {
            this.product.increaseStock(this.quantity);
        }
    }

    public void connectToOrder(Order order) {
        this.order = order;
    }
}
profile
공부하는 초보 개발자

0개의 댓글