diff --git a/src/main/java/com/programmers/springbootjpa/controller/CustomerController.java b/src/main/java/com/programmers/springbootjpa/controller/CustomerController.java new file mode 100644 index 000000000..5e1a07a6a --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/controller/CustomerController.java @@ -0,0 +1,49 @@ +package com.programmers.springbootjpa.controller; + +import com.programmers.springbootjpa.dto.CustomerCreateRequest; +import com.programmers.springbootjpa.dto.CustomerResponse; +import com.programmers.springbootjpa.dto.CustomerUpdateRequest; +import com.programmers.springbootjpa.service.CustomerService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/customer") +@RequiredArgsConstructor +public class CustomerController { + + private final CustomerService customerService; + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public CustomerResponse createCustomer(@RequestBody CustomerCreateRequest request) { + return customerService.createCustomer(request); + } + + @GetMapping + public List findAllCustomers() { + return customerService.findAllCustomers(); + } + + @PatchMapping("/{id}") + public CustomerResponse updateCustomerById(@PathVariable Long id, + @RequestBody CustomerUpdateRequest request) { + return customerService.updateCustomerById(id, request); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteCustomerById(@PathVariable Long id) { + customerService.deleteCustomerById(id); + } +} diff --git a/src/main/java/com/programmers/springbootjpa/domain/Customer.java b/src/main/java/com/programmers/springbootjpa/domain/Customer.java new file mode 100644 index 000000000..05777aaa2 --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/domain/Customer.java @@ -0,0 +1,54 @@ +package com.programmers.springbootjpa.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "customer") +@Getter +@NoArgsConstructor +public class Customer { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false, length = 30) + private String name; + + @Column(name = "age") + private Integer age; + + @Column(name = "nick_name", nullable = false, length = 30, unique = true) + private String nickName; + + @Column(name = "address", nullable = false, length = 100) + private String address; + + @Builder + public Customer(String name, Integer age, String nickName, String address) { + this.name = name; + this.age = age; + this.nickName = nickName; + this.address = address; + } + + public void updateName(String name) { + this.name = name; + } + + public void updateAge(Integer age) { + this.age = age; + } + + public void updateAddress(String address) { + this.address = address; + } +} diff --git a/src/main/java/com/programmers/springbootjpa/dto/CustomerCreateRequest.java b/src/main/java/com/programmers/springbootjpa/dto/CustomerCreateRequest.java new file mode 100644 index 000000000..bf06cd5e0 --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/dto/CustomerCreateRequest.java @@ -0,0 +1,26 @@ +package com.programmers.springbootjpa.dto; + +import com.programmers.springbootjpa.domain.Customer; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class CustomerCreateRequest { + + private String name; + private Integer age; + private String nickName; + private String address; + + public Customer toEntity() { + return Customer.builder() + .name(name) + .age(age) + .nickName(nickName) + .address(address) + .build(); + } +} diff --git a/src/main/java/com/programmers/springbootjpa/dto/CustomerResponse.java b/src/main/java/com/programmers/springbootjpa/dto/CustomerResponse.java new file mode 100644 index 000000000..934054fb4 --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/dto/CustomerResponse.java @@ -0,0 +1,26 @@ +package com.programmers.springbootjpa.dto; + +import com.programmers.springbootjpa.domain.Customer; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class CustomerResponse { + + private Long id; + private String name; + private Integer age; + private String nickName; + private String address; + + public static CustomerResponse fromEntity(Customer customer) { + return new CustomerResponse( + customer.getId(), + customer.getName(), + customer.getAge(), + customer.getNickName(), + customer.getAddress() + ); + } +} diff --git a/src/main/java/com/programmers/springbootjpa/dto/CustomerUpdateRequest.java b/src/main/java/com/programmers/springbootjpa/dto/CustomerUpdateRequest.java new file mode 100644 index 000000000..5cdf8f1c9 --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/dto/CustomerUpdateRequest.java @@ -0,0 +1,13 @@ +package com.programmers.springbootjpa.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class CustomerUpdateRequest { + + private String name; + private Integer age; + private String address; +} diff --git a/src/main/java/com/programmers/springbootjpa/repository/CustomerRepository.java b/src/main/java/com/programmers/springbootjpa/repository/CustomerRepository.java new file mode 100644 index 000000000..bf639bb3a --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/repository/CustomerRepository.java @@ -0,0 +1,8 @@ +package com.programmers.springbootjpa.repository; + +import com.programmers.springbootjpa.domain.Customer; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CustomerRepository extends JpaRepository { + +} diff --git a/src/main/java/com/programmers/springbootjpa/service/CustomerService.java b/src/main/java/com/programmers/springbootjpa/service/CustomerService.java new file mode 100644 index 000000000..b24c05592 --- /dev/null +++ b/src/main/java/com/programmers/springbootjpa/service/CustomerService.java @@ -0,0 +1,54 @@ +package com.programmers.springbootjpa.service; + +import com.programmers.springbootjpa.domain.Customer; +import com.programmers.springbootjpa.dto.CustomerCreateRequest; +import com.programmers.springbootjpa.dto.CustomerResponse; +import com.programmers.springbootjpa.dto.CustomerUpdateRequest; +import com.programmers.springbootjpa.repository.CustomerRepository; +import java.util.List; +import java.util.NoSuchElementException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CustomerService { + + private final CustomerRepository customerRepository; + + @Transactional + public CustomerResponse createCustomer(CustomerCreateRequest request) { + Customer savedCustomer = customerRepository.save(request.toEntity()); + + return CustomerResponse.fromEntity(savedCustomer); + } + + public List findAllCustomers() { + return customerRepository.findAll() + .stream() + .map(CustomerResponse::fromEntity) + .toList(); + } + + @Transactional + public CustomerResponse updateCustomerById(Long id, CustomerUpdateRequest request) { + Customer customer = customerRepository.findById(id) + .orElseThrow(() -> new NoSuchElementException("해당 ID에 해당하는 구매자가 없습니다.")); + + customer.updateName(request.getName()); + customer.updateAge(request.getAge()); + customer.updateAddress(request.getAddress()); + + return CustomerResponse.fromEntity(customer); + } + + @Transactional + public void deleteCustomerById(Long id) { + if (!customerRepository.existsById(id)) { + throw new NoSuchElementException("해당 ID에 해당하는 구매자가 없습니다."); + } + + customerRepository.deleteById(id); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 8b1378917..000000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 000000000..2156c633d --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,10 @@ +spring: + datasource: + driver-class-name: org.h2.Driver + username: sa + password: + jpa: + hibernate: + ddl-auto: create-drop + database-platform: org.hibernate.dialect.H2Dialect + show-sql: true \ No newline at end of file diff --git a/src/test/java/com/programmers/springbootjpa/domain/CustomerTest.java b/src/test/java/com/programmers/springbootjpa/domain/CustomerTest.java new file mode 100644 index 000000000..165a90e06 --- /dev/null +++ b/src/test/java/com/programmers/springbootjpa/domain/CustomerTest.java @@ -0,0 +1,32 @@ +package com.programmers.springbootjpa.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.programmers.springbootjpa.dto.CustomerCreateRequest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class CustomerTest { + + @Test + @DisplayName("Customer 생성 Dto에서 Customer Entity로 정상적으로 변환되는지 테스트한다.") + void customerDtoToEntityTest() { + CustomerCreateRequest request = new CustomerCreateRequest( + "Kim Jae Won", + 28, + "hanjo", + "서울시 마포구" + ); + + Customer actualEntity = request.toEntity(); + + Customer expectedEntity = Customer.builder() + .name("Kim Jae Won") + .age(28) + .nickName("hanjo") + .address("서울시 마포구") + .build(); + + assertThat(actualEntity).usingRecursiveComparison().isEqualTo(expectedEntity); + } +}