[#5] Refactor: 코틀린 베이스 프로젝트로 리팩토링

- Cafe, CafeMenu 도메인 내용 코틀린 변환
This commit is contained in:
beaniejoy
2022-06-22 20:09:55 +09:00
parent 9d7850e7d1
commit d12f92a8e5
26 changed files with 164 additions and 235 deletions

View File

@@ -1,9 +0,0 @@
package io.beaniejoy.dongnecafe.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableJpaAuditing
public class AuditingConfig {
}

View File

@@ -0,0 +1,8 @@
package io.beaniejoy.dongnecafe.common.config
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaAuditing
@Configuration
@EnableJpaAuditing
class AuditingConfig

View File

@@ -9,10 +9,10 @@ import javax.persistence.MappedSuperclass
@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
open class BaseTimeEntity {
open class BaseTimeEntity(
@CreatedDate
private val createdDate: LocalDateTime? = null
val createdAt: LocalDateTime = LocalDateTime.now(),
@LastModifiedDate
private val updatedDate: LocalDateTime? = null
}
val updatedAt: LocalDateTime? = null
)

View File

@@ -8,9 +8,7 @@ import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Sort
import org.springframework.data.web.PageableDefault
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
@RestController
@RequestMapping("/cafes")
@@ -24,18 +22,17 @@ class CafeController(
return cafeService.getCafeList(pageable)
}
@GetMapping("/{cafeId}")
fun getCafeDetailedInfo(@PathVariable("cafeId") cafeId: UUID): ResponseEntity<CafeInfoResponseDto> {
val cafeResponse = cafeService.getCafeInfoByCafeId(cafeId)
return ResponseEntity.ok(cafeResponse)
@GetMapping("/{id}")
fun getCafeDetailedInfo(@PathVariable("id") id: Long): CafeInfoResponseDto {
return cafeService.getCafeInfoByCafeId(id)
}
// TODO spring boot validation 적용 필요
@PutMapping("/{id}")
fun updateCafeInfo(
@PathVariable("id") id: UUID,
@PathVariable("id") id: Long,
@RequestBody resource: CafeUpdateRequestDto
): ResponseEntity<String> {
): String {
cafeService.updateCafe(
id = id,
name = resource.name!!,
@@ -44,6 +41,6 @@ class CafeController(
description = resource.description!!
)
return ResponseEntity.ok("Successfully Cafe[$id] Info Updated")
return "Successfully Cafe[$id] Info Updated"
}
}

View File

@@ -1,28 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.controller;
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto;
import io.beaniejoy.dongnecafe.domain.cafe.service.CafeMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@RequiredArgsConstructor
public class CafeMenuController {
private final CafeMenuService cafeMenuService;
@GetMapping("/cafes/{cafeId}/menus/{menuId}")
public ResponseEntity<CafeMenuDetailResponseDto> getCafeMenuDetailedInfo(
@PathVariable("cafeId") UUID cafeId,
@PathVariable("menuId") UUID menuId
) {
CafeMenuDetailResponseDto menuDetail = cafeMenuService.getCafeMenuInfoByCafeIdAndMenuId(menuId, cafeId);
return ResponseEntity.ok(menuDetail);
}
}

View File

@@ -0,0 +1,23 @@
package io.beaniejoy.dongnecafe.domain.cafe.controller
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto
import io.beaniejoy.dongnecafe.domain.cafe.service.CafeMenuService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RestController
@RestController
class CafeMenuController(
private val cafeMenuService: CafeMenuService
) {
@GetMapping("/cafes/{cafeId}/menus/{menuId}")
fun getCafeMenuDetailedInfo(
@PathVariable("cafeId") cafeId: Long,
@PathVariable("menuId") menuId: Long
): CafeMenuDetailResponseDto {
return cafeMenuService.getCafeMenuInfoByCafeIdAndMenuId(
menuId = menuId,
cafeId = cafeId
)
}
}

View File

@@ -1,16 +1,13 @@
package io.beaniejoy.dongnecafe.domain.cafe.domain
import io.beaniejoy.dongnecafe.common.domain.BaseTimeEntity
import io.beaniejoy.dongnecafe.domain.cafe.dto.cafe.CafeInfoResponseDto
import io.beaniejoy.dongnecafe.domain.cafe.dto.cafe.CafeSearchResponseDto
import java.util.stream.Collectors
import javax.persistence.*
@Entity(name = "cafe")
class Cafe(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long,
val id: Long = 0L,
@Column(name = "name")
var name: String,

View File

@@ -1,59 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.domain;
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto;
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuListResponseDto;
import io.beaniejoy.dongnecafe.common.domain.BaseTimeEntity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class CafeMenu extends BaseTimeEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "menu_id", columnDefinition = "BINARY(16)")
private UUID menuId;
private String name;
private Integer price;
@ManyToOne
@JoinColumn(name = "cafe_id")
private Cafe cafe;
@OneToMany(mappedBy = "cafeMenu", fetch = FetchType.LAZY)
private List<MenuOption> menuOptionList;
public CafeMenuListResponseDto toListResponseDto() {
return CafeMenuListResponseDto.builder()
.menuId(menuId)
.name(name)
.price(price)
.build();
}
public CafeMenuDetailResponseDto toDetailResponseDto() {
return CafeMenuDetailResponseDto.builder()
.name(name)
.price(price)
.optionList(menuOptionList
.stream()
.map(MenuOption::toResponseDto)
.collect(Collectors.toList()))
.build();
}
}

View File

@@ -0,0 +1,25 @@
package io.beaniejoy.dongnecafe.domain.cafe.domain
import io.beaniejoy.dongnecafe.common.domain.BaseTimeEntity
import java.math.BigDecimal
import javax.persistence.*
@Entity(name = "cafe_menu")
class CafeMenu(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
@Column(name = "name")
val name: String,
@Column(name = "price")
val price: BigDecimal = BigDecimal.ZERO,
@ManyToOne
@JoinColumn(name = "cafe_id")
val cafe: Cafe,
@OneToMany(mappedBy = "cafeMenu", fetch = FetchType.LAZY)
val menuOptionList: MutableList<MenuOption>
) : BaseTimeEntity()

View File

@@ -1,7 +1,7 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.cafe
import io.beaniejoy.dongnecafe.domain.cafe.domain.Cafe
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuListResponseDto
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuResponseDto
data class CafeInfoResponseDto(
val id: Long? = null,
@@ -10,7 +10,7 @@ data class CafeInfoResponseDto(
val phoneNumber: String? = null,
val totalRate: Double? = null,
val description: String? = null,
val menuList: List<CafeMenuListResponseDto> = emptyList(),
val menuList: List<CafeMenuResponseDto> = emptyList(),
val imageList: List<CafeImageResponseDto> = emptyList()
) {
companion object {
@@ -22,7 +22,7 @@ data class CafeInfoResponseDto(
phoneNumber = cafe.phoneNumber,
totalRate = cafe.totalRate,
description = cafe.description,
menuList = cafe.cafeMenuList.map { it.toListResponseDto() },
menuList = cafe.cafeMenuList.map { CafeMenuResponseDto.of(it) },
imageList = cafe.cafeImageList.map { CafeImageResponseDto.of(it) }
)
}

View File

@@ -1,21 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.menu;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.List;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CafeMenuDetailResponseDto {
private String name;
private Integer price;
private List<MenuOptionResponseDto> optionList;
}

View File

@@ -0,0 +1,20 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.menu
import io.beaniejoy.dongnecafe.domain.cafe.domain.CafeMenu
import java.math.BigDecimal
data class CafeMenuDetailResponseDto(
val name: String? = null,
val price: BigDecimal = BigDecimal.ZERO,
val optionList: List<MenuOptionResponseDto> = emptyList()
) {
companion object {
fun of(cafeMenu: CafeMenu): CafeMenuDetailResponseDto {
return CafeMenuDetailResponseDto(
name = cafeMenu.name,
price = cafeMenu.price,
optionList = cafeMenu.menuOptionList.map { it.toResponseDto() }
)
}
}
}

View File

@@ -1,21 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.menu;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CafeMenuListResponseDto {
private UUID menuId;
private String name;
private Integer price;
}

View File

@@ -0,0 +1,20 @@
package io.beaniejoy.dongnecafe.domain.cafe.dto.menu
import io.beaniejoy.dongnecafe.domain.cafe.domain.CafeMenu
import java.math.BigDecimal
data class CafeMenuResponseDto(
val id: Long = 0L,
val name: String? = null,
val price: BigDecimal = BigDecimal.ZERO,
) {
companion object {
fun of(cafeMenu: CafeMenu): CafeMenuResponseDto {
return CafeMenuResponseDto(
id = cafeMenu.id,
name = cafeMenu.name,
price = cafeMenu.price
)
}
}
}

View File

@@ -1,14 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.error;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class CafeExceptionHandler {
@ExceptionHandler(CafeNotFoundException.class)
public ResponseEntity<String> handleNotFound(CafeNotFoundException exception) {
return ResponseEntity.badRequest().body(exception.getMessage());
}
}

View File

@@ -0,0 +1,13 @@
package io.beaniejoy.dongnecafe.domain.cafe.error
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice
@RestControllerAdvice
class CafeExceptionHandler {
@ExceptionHandler(CafeNotFoundException::class)
fun handleNotFound(exception: CafeNotFoundException): ResponseEntity<String> {
return ResponseEntity.badRequest().body(exception.message)
}
}

View File

@@ -1,9 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.error;
import java.util.UUID;
public class CafeMenuNotFoundException extends RuntimeException{
public CafeMenuNotFoundException(UUID menuId, UUID cafeId) {
super("Cafe[" + cafeId + "]의 Menu[" + menuId + "]는 존재하지 않는 메뉴입니다.");
}
}

View File

@@ -0,0 +1,4 @@
package io.beaniejoy.dongnecafe.domain.cafe.error
class CafeMenuNotFoundException(menuId: Long, cafeId: Long) :
RuntimeException("Cafe[${cafeId}]의 Menu[${menuId}]는 존재하지 않는 메뉴입니다.")

View File

@@ -1,9 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.error;
import java.util.UUID;
public class CafeNotFoundException extends RuntimeException {
public CafeNotFoundException(UUID cafeId) {
super("Cafe[" + cafeId + "] is not found");
}
}

View File

@@ -0,0 +1,3 @@
package io.beaniejoy.dongnecafe.domain.cafe.error
class CafeNotFoundException(cafeId: Long) : RuntimeException("Cafe[$cafeId] is not found")

View File

@@ -1,9 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.repository;
import io.beaniejoy.dongnecafe.domain.cafe.domain.CafeMenu;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface CafeMenuRepository extends JpaRepository<CafeMenu, UUID> {
}

View File

@@ -0,0 +1,6 @@
package io.beaniejoy.dongnecafe.domain.cafe.repository
import io.beaniejoy.dongnecafe.domain.cafe.domain.CafeMenu
import org.springframework.data.jpa.repository.JpaRepository
interface CafeMenuRepository : JpaRepository<CafeMenu, Long>

View File

@@ -1,10 +1,7 @@
package io.beaniejoy.dongnecafe.domain.cafe.repository
import io.beaniejoy.dongnecafe.domain.cafe.domain.Cafe
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import java.util.*
interface CafeRepository : JpaRepository<Cafe, UUID> {
interface CafeRepository : JpaRepository<Cafe, Long> {
}

View File

@@ -1,27 +0,0 @@
package io.beaniejoy.dongnecafe.domain.cafe.service;
import io.beaniejoy.dongnecafe.domain.cafe.domain.CafeMenu;
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto;
import io.beaniejoy.dongnecafe.domain.cafe.error.CafeMenuNotFoundException;
import io.beaniejoy.dongnecafe.domain.cafe.repository.CafeMenuRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.UUID;
@Service
@RequiredArgsConstructor
public class CafeMenuService {
private final CafeMenuRepository cafeMenuRepository;
@Transactional(readOnly = true)
public CafeMenuDetailResponseDto getCafeMenuInfoByCafeIdAndMenuId(UUID menuId, UUID cafeId) {
CafeMenu cafeMenu = cafeMenuRepository.findById(menuId)
.orElseThrow(() -> new CafeMenuNotFoundException(menuId, cafeId));
return cafeMenu.toDetailResponseDto();
}
}

View File

@@ -0,0 +1,23 @@
package io.beaniejoy.dongnecafe.domain.cafe.service
import io.beaniejoy.dongnecafe.domain.cafe.dto.menu.CafeMenuDetailResponseDto
import io.beaniejoy.dongnecafe.domain.cafe.error.CafeMenuNotFoundException
import io.beaniejoy.dongnecafe.domain.cafe.repository.CafeMenuRepository
import lombok.RequiredArgsConstructor
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
@RequiredArgsConstructor
class CafeMenuService(
private val cafeMenuRepository: CafeMenuRepository
) {
@Transactional(readOnly = true)
fun getCafeMenuInfoByCafeIdAndMenuId(menuId: Long, cafeId: Long): CafeMenuDetailResponseDto {
val cafeMenu = cafeMenuRepository.findByIdOrNull(menuId)
?: throw CafeMenuNotFoundException(menuId, cafeId)
return CafeMenuDetailResponseDto.of(cafeMenu)
}
}

View File

@@ -9,7 +9,6 @@ import org.springframework.data.domain.Pageable
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
@Service
@Transactional
@@ -25,15 +24,15 @@ class CafeService(
}
@Transactional(readOnly = true)
fun getCafeInfoByCafeId(cafeId: UUID): CafeInfoResponseDto {
val cafe = cafeRepository.findByIdOrNull(cafeId)
?: throw CafeNotFoundException(cafeId)
fun getCafeInfoByCafeId(id: Long): CafeInfoResponseDto {
val cafe = cafeRepository.findByIdOrNull(id)
?: throw CafeNotFoundException(id)
return CafeInfoResponseDto.of(cafe)
}
fun updateCafe(
id: UUID,
id: Long,
name: String,
address: String,
phoneNumber: String,