From 98c004deddfb0e36b018d76354d90ce57950f475 Mon Sep 17 00:00:00 2001 From: kmebin Date: Wed, 26 Jul 2023 09:43:26 +0900 Subject: [PATCH 01/10] =?UTF-8?q?init:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 49 +++++++++++++++++++ build.gradle | 38 ++++++++++++++ settings.gradle | 1 + .../jpabasic/JpaBasicApplication.java | 12 +++++ src/main/resources/application.yml | 18 +++++++ .../jpabasic/JpaBasicApplicationTests.java | 12 +++++ 6 files changed, 130 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle create mode 100644 settings.gradle create mode 100644 src/main/java/com/programmers/jpabasic/JpaBasicApplication.java create mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..0de3cb43a --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +HELP.md + +### Gradle ### +gradle/ +gradlew +gradlew.bat +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store + +### Log files ### +logs/ +*.log diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..f5efa886b --- /dev/null +++ b/build.gradle @@ -0,0 +1,38 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '2.7.14' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' +} + +group = 'com.programmers' +version = '0.0.1-SNAPSHOT' + +java { + sourceCompatibility = '17' +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + runtimeOnly 'com.h2database:h2' + + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..c58e92312 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'jpa-basic' diff --git a/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java b/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java new file mode 100644 index 000000000..bfc6e7ba8 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java @@ -0,0 +1,12 @@ +package com.programmers.jpabasic; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JpaBasicApplication { + + public static void main(String[] args) { + SpringApplication.run(JpaBasicApplication.class, args); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 000000000..5561cb876 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,18 @@ +spring: + h2: + console: + enabled: true + + jpa: + generate-ddl: true + hibernate: + ddl-auto: create-drop + database: H2 + show-sql: true + open-in-view: false + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + query: + in_clause_parameter_padding: true + format_sql: true diff --git a/src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java b/src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java new file mode 100644 index 000000000..ef92be354 --- /dev/null +++ b/src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java @@ -0,0 +1,12 @@ +package com.programmers.jpabasic; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class JpaBasicApplicationTests { + + @Test + void contextLoads() { + } +} From f2d7435d4880d4e2166f1f46e4fb6bb5248bf7d9 Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 19:05:15 +0900 Subject: [PATCH 02/10] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20CRUD=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jpabasic/JpaBasicApplication.java | 2 + .../domain/customer/entity/Customer.java | 33 +++++++ .../jpabasic/domain/customer/entity/Name.java | 31 ++++++ .../repository/CustomerRepository.java | 8 ++ .../jpabasic/global/common/BaseEntity.java | 34 +++++++ src/main/resources/application.yml | 13 --- .../repository/CustomerRepositoryTest.java | 96 +++++++++++++++++++ .../jpabasic/support/CustomerFixture.java | 13 +++ 8 files changed, 217 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/programmers/jpabasic/domain/customer/entity/Customer.java create mode 100644 src/main/java/com/programmers/jpabasic/domain/customer/entity/Name.java create mode 100644 src/main/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepository.java create mode 100644 src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java create mode 100644 src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java create mode 100644 src/test/java/com/programmers/jpabasic/support/CustomerFixture.java diff --git a/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java b/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java index bfc6e7ba8..e574da9be 100644 --- a/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java +++ b/src/main/java/com/programmers/jpabasic/JpaBasicApplication.java @@ -2,7 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +@EnableJpaAuditing @SpringBootApplication public class JpaBasicApplication { diff --git a/src/main/java/com/programmers/jpabasic/domain/customer/entity/Customer.java b/src/main/java/com/programmers/jpabasic/domain/customer/entity/Customer.java new file mode 100644 index 000000000..8f7d8527a --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/customer/entity/Customer.java @@ -0,0 +1,33 @@ +package com.programmers.jpabasic.domain.customer.entity; + +import javax.persistence.Embedded; +import javax.persistence.Entity; + +import com.programmers.jpabasic.global.common.BaseEntity; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Customer extends BaseEntity { + + @Embedded + private Name name; + + public static Customer create(String firstName, String lastName) { + return Customer.builder() + .name(Name.of(firstName, lastName)) + .build(); + } + + public void updateName(String firstName, String lastName) { + this.name = Name.of(firstName, lastName); + } +} diff --git a/src/main/java/com/programmers/jpabasic/domain/customer/entity/Name.java b/src/main/java/com/programmers/jpabasic/domain/customer/entity/Name.java new file mode 100644 index 000000000..525420581 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/customer/entity/Name.java @@ -0,0 +1,31 @@ +package com.programmers.jpabasic.domain.customer.entity; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@Embeddable +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Name { + + @Column(nullable = false, length = 30) + private String firstName; + + @Column(nullable = false, length = 20) + private String lastName; + + public static Name of(String firstName, String lastName) { + return Name.builder() + .firstName(firstName) + .lastName(lastName) + .build(); + } +} diff --git a/src/main/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepository.java b/src/main/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepository.java new file mode 100644 index 000000000..03bd882b1 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepository.java @@ -0,0 +1,8 @@ +package com.programmers.jpabasic.domain.customer.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.programmers.jpabasic.domain.customer.entity.Customer; + +public interface CustomerRepository extends JpaRepository { +} diff --git a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java new file mode 100644 index 000000000..4faa20a87 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java @@ -0,0 +1,34 @@ +package com.programmers.jpabasic.global.common; + +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import lombok.Getter; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @CreatedDate + @Column(columnDefinition = "TIMESTAMP") + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(columnDefinition = "TIMESTAMP") + private LocalDateTime updatedAt; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5561cb876..c2ab783bc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,18 +1,5 @@ spring: - h2: - console: - enabled: true - jpa: - generate-ddl: true - hibernate: - ddl-auto: create-drop - database: H2 - show-sql: true - open-in-view: false properties: hibernate: - dialect: org.hibernate.dialect.MySQL5InnoDBDialect - query: - in_clause_parameter_padding: true format_sql: true diff --git a/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java b/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java new file mode 100644 index 000000000..96398d039 --- /dev/null +++ b/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java @@ -0,0 +1,96 @@ +package com.programmers.jpabasic.domain.customer.repository; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import com.programmers.jpabasic.domain.customer.entity.Customer; +import com.programmers.jpabasic.support.CustomerFixture; + +@DataJpaTest +class CustomerRepositoryTest { + + @Autowired + private CustomerRepository customerRepository; + + @Test + @DisplayName("고객 저장에 성공한다.") + void save() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + + // when + customerRepository.save(customer); + + // then + Customer result = customerRepository.findById(customer.getId()).orElseThrow(); + assertThat(result.getName().getFirstName()).isEqualTo("heebin"); + assertThat(result.getName().getLastName()).isEqualTo("kim"); + } + + @Test + @DisplayName("모든 고객 조회에 성공한다.") + void findAll() { + // given + Customer customer1 = CustomerFixture.create("heebin", "kim"); + Customer customer2 = CustomerFixture.create("희빈", "김"); + + customerRepository.save(customer1); + customerRepository.save(customer2); + + // when + List result = customerRepository.findAll(); + + // then + assertThat(result).hasSize(2).contains(customer1, customer2); + } + + @Test + @DisplayName("고객 ID로 조회에 성공한다.") + void findById() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + customerRepository.save(customer); + + // when + Customer result = customerRepository.findById(customer.getId()).orElseThrow(); + + // then + assertThat(result).isNotNull().isEqualTo(customer); + } + + @Test + @DisplayName("고객 수정에 성공한다.") + void update() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + customerRepository.save(customer); + + // when + customer.updateName("희빈", "김"); + + // then + Customer result = customerRepository.findById(customer.getId()).orElseThrow(); + assertThat(result.getName().getFirstName()).isEqualTo("희빈"); + assertThat(result.getName().getLastName()).isEqualTo("김"); + } + + @Test + @DisplayName("고객 삭제에 성공한다.") + void delete() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + customerRepository.save(customer); + + // when + customerRepository.delete(customer); + + // then + assertThat(customerRepository.findById(customer.getId())).isEmpty(); + } +} diff --git a/src/test/java/com/programmers/jpabasic/support/CustomerFixture.java b/src/test/java/com/programmers/jpabasic/support/CustomerFixture.java new file mode 100644 index 000000000..eede3104b --- /dev/null +++ b/src/test/java/com/programmers/jpabasic/support/CustomerFixture.java @@ -0,0 +1,13 @@ +package com.programmers.jpabasic.support; + +import com.programmers.jpabasic.domain.customer.entity.Customer; +import com.programmers.jpabasic.domain.customer.entity.Name; + +public class CustomerFixture { + public static Customer create(String firstName, String lastName) { + return Customer + .builder() + .name(Name.of(firstName, lastName)) + .build(); + } +} From 5bfc3f890f647cbc82e79322bdd55dca6ad23ba5 Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 19:33:28 +0900 Subject: [PATCH 03/10] =?UTF-8?q?test:=20ID=EB=A1=9C=20=EA=B3=A0=EA=B0=9D?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EA=B2=80=EC=A6=9D=EB=B6=80?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/customer/repository/CustomerRepositoryTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java b/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java index 96398d039..4e4ad1ca9 100644 --- a/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java +++ b/src/test/java/com/programmers/jpabasic/domain/customer/repository/CustomerRepositoryTest.java @@ -61,7 +61,8 @@ void findById() { Customer result = customerRepository.findById(customer.getId()).orElseThrow(); // then - assertThat(result).isNotNull().isEqualTo(customer); + assertThat(result.getName().getFirstName()).isEqualTo("heebin"); + assertThat(result.getName().getLastName()).isEqualTo("kim"); } @Test From 380985a143991ab36d48639c51b9c5d4ce84a027 Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 19:45:40 +0900 Subject: [PATCH 04/10] =?UTF-8?q?test:=20Customer=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=83=9D=EB=AA=85=20=EC=A3=BC=EA=B8=B0=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/CustomerPersistenceTest.java | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/test/java/com/programmers/jpabasic/domain/customer/entity/CustomerPersistenceTest.java diff --git a/src/test/java/com/programmers/jpabasic/domain/customer/entity/CustomerPersistenceTest.java b/src/test/java/com/programmers/jpabasic/domain/customer/entity/CustomerPersistenceTest.java new file mode 100644 index 000000000..b6712282e --- /dev/null +++ b/src/test/java/com/programmers/jpabasic/domain/customer/entity/CustomerPersistenceTest.java @@ -0,0 +1,122 @@ +package com.programmers.jpabasic.domain.customer.entity; + +import static org.assertj.core.api.Assertions.*; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import com.programmers.jpabasic.support.CustomerFixture; + +@DataJpaTest +class CustomerPersistenceTest { + + @Autowired + private EntityManagerFactory entityManagerFactory; + + private EntityManager entityManager; + private EntityTransaction transaction; + + @BeforeEach + void setUp() { + entityManager = entityManagerFactory.createEntityManager(); + transaction = entityManager.getTransaction(); + transaction.begin(); + } + + @Test + @DisplayName("고객 저장에 성공한다.") + void save() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + + // when + entityManager.persist(customer); + transaction.commit(); + + // then + Customer result = entityManager.find(Customer.class, customer.getId()); + assertThat(result.getName().getFirstName()).isEqualTo("heebin"); + assertThat(result.getName().getLastName()).isEqualTo("kim"); + } + + @Test + @DisplayName("DB로부터 고객 조회에 성공한다.") + void findFromDB() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + + entityManager.persist(customer); + transaction.commit(); + + // when + entityManager.detach(customer); + Customer result = entityManager.find(Customer.class, customer.getId()); + + // then + assertThat(result.getName().getFirstName()).isEqualTo("heebin"); + assertThat(result.getName().getLastName()).isEqualTo("kim"); + } + + @Test + @DisplayName("1차 캐시로부터 고객 조회에 성공한다.") + void findFromCache() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + + entityManager.persist(customer); + transaction.commit(); + + // when + Customer result = entityManager.find(Customer.class, customer.getId()); + + // then + assertThat(result.getName().getFirstName()).isEqualTo("heebin"); + assertThat(result.getName().getLastName()).isEqualTo("kim"); + } + + @Test + @DisplayName("고객 수정에 성공한다.") + void update() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + + entityManager.persist(customer); + transaction.commit(); + + // when + transaction.begin(); + customer.updateName("희빈", "김"); + transaction.commit(); + + // then + Customer result = entityManager.find(Customer.class, customer.getId()); + assertThat(result.getName().getFirstName()).isEqualTo("희빈"); + assertThat(result.getName().getLastName()).isEqualTo("김"); + } + + @Test + @DisplayName("고객 삭제에 성공한다.") + void delete() { + // given + Customer customer = CustomerFixture.create("heebin", "kim"); + + entityManager.persist(customer); + transaction.commit(); + + // when + transaction.begin(); + entityManager.remove(customer); + transaction.commit(); + + // then + Customer result = entityManager.find(Customer.class, customer.getId()); + assertThat(result).isNull(); + } +} From cb3d2400d96d237e6e116a27167c2be1dd025eed Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 19:54:01 +0900 Subject: [PATCH 05/10] =?UTF-8?q?feat:=20createdAt,=20updatedAt=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=EC=97=90=20not=20null=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/programmers/jpabasic/global/common/BaseEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java index 4faa20a87..a26058c9e 100644 --- a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java +++ b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java @@ -25,10 +25,10 @@ public abstract class BaseEntity { private Long id; @CreatedDate - @Column(columnDefinition = "TIMESTAMP") + @Column(nullable = false, columnDefinition = "TIMESTAMP") private LocalDateTime createdAt; @LastModifiedDate - @Column(columnDefinition = "TIMESTAMP") + @Column(nullable = false, columnDefinition = "TIMESTAMP") private LocalDateTime updatedAt; } From ce16b8df42e622687cbf42e7f3b63fdc059a0195 Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 21:55:12 +0900 Subject: [PATCH 06/10] =?UTF-8?q?feat:=20Order,=20OrderItem,=20Item=20?= =?UTF-8?q?=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jpabasic/domain/member/entity/Member.java | 35 ++++++++++++++ .../jpabasic/domain/order/entity/Item.java | 26 +++++++++++ .../jpabasic/domain/order/entity/Order.java | 46 +++++++++++++++++++ .../domain/order/entity/OrderItem.java | 36 +++++++++++++++ .../domain/order/entity/OrderStatus.java | 5 ++ 5 files changed, 148 insertions(+) create mode 100644 src/main/java/com/programmers/jpabasic/domain/member/entity/Member.java create mode 100644 src/main/java/com/programmers/jpabasic/domain/order/entity/Item.java create mode 100644 src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java create mode 100644 src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java create mode 100644 src/main/java/com/programmers/jpabasic/domain/order/entity/OrderStatus.java diff --git a/src/main/java/com/programmers/jpabasic/domain/member/entity/Member.java b/src/main/java/com/programmers/jpabasic/domain/member/entity/Member.java new file mode 100644 index 000000000..027d3943c --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/member/entity/Member.java @@ -0,0 +1,35 @@ +package com.programmers.jpabasic.domain.member.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; + +import com.programmers.jpabasic.global.common.BaseEntity; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Member extends BaseEntity { + + @Column(nullable = false, length = 50) + private String name; + + @Column(nullable = false, length = 30, unique = true) + private String nickname; + + @Column + private int age; + + @Column(nullable = false) + private String address; + + @Column(length = 100) + private String description; +} diff --git a/src/main/java/com/programmers/jpabasic/domain/order/entity/Item.java b/src/main/java/com/programmers/jpabasic/domain/order/entity/Item.java new file mode 100644 index 000000000..2fcfb83fc --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/order/entity/Item.java @@ -0,0 +1,26 @@ +package com.programmers.jpabasic.domain.order.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; + +import com.programmers.jpabasic.global.common.BaseEntity; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Item extends BaseEntity { + + @Column(nullable = false) + private int price; + + @Column + private int stockQuantity; +} diff --git a/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java b/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java new file mode 100644 index 000000000..5d5cb29f6 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java @@ -0,0 +1,46 @@ +package com.programmers.jpabasic.domain.order.entity; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.JoinColumn; +import javax.persistence.Lob; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import com.programmers.jpabasic.domain.member.entity.Member; +import com.programmers.jpabasic.global.common.BaseEntity; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder +@Table(name = "orders") +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Order extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "member_id") + private Member member; + + @Column(nullable = false) + @Enumerated(value = EnumType.STRING) + private OrderStatus status; + + @Lob + private String memo; + + @OneToMany(mappedBy = "order") + private final List orderItems = new ArrayList<>(); +} diff --git a/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java b/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java new file mode 100644 index 000000000..4f9f9f855 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java @@ -0,0 +1,36 @@ +package com.programmers.jpabasic.domain.order.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import com.programmers.jpabasic.global.common.BaseEntity; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrderItem extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "order_id") + private Order order; + + @ManyToOne + @JoinColumn(name = "item_id") + private Item item; + + @Column(nullable = false) + private int price; + + @Column(nullable = false) + private int quantity; +} diff --git a/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderStatus.java b/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderStatus.java new file mode 100644 index 000000000..a6342b979 --- /dev/null +++ b/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderStatus.java @@ -0,0 +1,5 @@ +package com.programmers.jpabasic.domain.order.entity; + +public enum OrderStatus { + OPENED, CANCELLED +} From 5251dfa5c60ee270224e18f33ecd8959e7fef4cb Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 22:03:12 +0900 Subject: [PATCH 07/10] =?UTF-8?q?chore:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jpabasic/JpaBasicApplicationTests.java | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java diff --git a/src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java b/src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java deleted file mode 100644 index ef92be354..000000000 --- a/src/test/java/com/programmers/jpabasic/JpaBasicApplicationTests.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.programmers.jpabasic; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class JpaBasicApplicationTests { - - @Test - void contextLoads() { - } -} From 0abf21a80d0b35aa934d8f8bd256952c56d2465c Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 23:46:20 +0900 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20id=20SEQUENCE=20=EC=A0=84=EB=9E=B5?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/programmers/jpabasic/global/common/BaseEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java index a26058c9e..73cd238b6 100644 --- a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java +++ b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java @@ -21,7 +21,7 @@ public abstract class BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; @CreatedDate From dc193927114a64b2f6f19bb99cdb1d05e2cac234 Mon Sep 17 00:00:00 2001 From: kmebin Date: Thu, 27 Jul 2023 23:50:27 +0900 Subject: [PATCH 09/10] =?UTF-8?q?feat:=20=EC=A7=80=EC=97=B0=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/programmers/jpabasic/domain/order/entity/Order.java | 3 ++- .../programmers/jpabasic/domain/order/entity/OrderItem.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java b/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java index 5d5cb29f6..491a65ce7 100644 --- a/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java +++ b/src/main/java/com/programmers/jpabasic/domain/order/entity/Order.java @@ -7,6 +7,7 @@ import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.ManyToOne; @@ -30,7 +31,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Order extends BaseEntity { - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; diff --git a/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java b/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java index 4f9f9f855..b0537d1fe 100644 --- a/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java +++ b/src/main/java/com/programmers/jpabasic/domain/order/entity/OrderItem.java @@ -2,6 +2,7 @@ import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @@ -20,11 +21,11 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class OrderItem extends BaseEntity { - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "order_id") private Order order; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "item_id") private Item item; From 0872ed8f2513dba1d6b4ce482aca1d5c46467cc4 Mon Sep 17 00:00:00 2001 From: kmebin Date: Fri, 28 Jul 2023 00:42:27 +0900 Subject: [PATCH 10/10] =?UTF-8?q?feat:=20createdAt=20=EC=86=8D=EC=84=B1?= =?UTF-8?q?=EC=97=90=20updatable=3Dfalse=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/programmers/jpabasic/global/common/BaseEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java index 73cd238b6..c95a683cf 100644 --- a/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java +++ b/src/main/java/com/programmers/jpabasic/global/common/BaseEntity.java @@ -25,7 +25,7 @@ public abstract class BaseEntity { private Long id; @CreatedDate - @Column(nullable = false, columnDefinition = "TIMESTAMP") + @Column(nullable = false, updatable = false, columnDefinition = "TIMESTAMP") private LocalDateTime createdAt; @LastModifiedDate