본문 바로가기

카테고리 없음

24.01.26 백오피스 카트수정

연관관계

테이블은 외래키를 객체는 id를 쓴다

onetomany하고 밑에 multiablelist mapped by

객체의 연관관계는 팀 회원, 회원 팀이렇게 단방향 둘 

테이블은 양방향

 

onetomanyt(mapped by = "team"이런식

 

양방향은 널에 위험함 그래서 안쓰는게 좋음

 

양방향을 쓸거면 순환구조로 그런데 양방향은 서로를 무한참조함 막으려면 toString(),내가 어재 쓴 Json이런거 쓰기

양방향 관계가 키는 누가 같나? order, item이 양방향이면 order_itrm을 만들어서 키를 준다

 

오더가 오더아이템에 일대다 오더아이템과 아이템이 다대일

 

onetoone은 헬스장 회원과 라커룸으로 키는 더 많이 쓰이는 쪽에?

 

@RestController
@RequestMapping("/carts")
class CartController(private val cartService: CartService) {

    @PostMapping
    fun addToCart(@AuthenticationPrincipal user: UserPrincipal, @RequestBody cartCreateDto: CartCreateDto): ResponseEntity<CartDto> {
        val memberId = user.id
        val cart = cartService.addToCart(cartCreateDto.menuId, cartCreateDto.storeId, memberId, cartCreateDto.count)
        return ResponseEntity.status(HttpStatus.CREATED).body(CartDto.from(cart))
    }

    @DeleteMapping("/{cartId}")
    fun removeFromCart(@AuthenticationPrincipal user: UserPrincipal, @PathVariable cartId: Long): ResponseEntity<String> {
        val memberId = user.id
        return try {
            cartService.removeFromCart(memberId, cartId)
            ResponseEntity.ok("성공적으로 제거하였습니다.")
        } catch (e: Exception) {
            ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("제거에 실패했습니다.")
        }
    }

    @DeleteMapping("/member/{memberId}")
    fun clearCart(@AuthenticationPrincipal user: UserPrincipal, @PathVariable memberId: String): ResponseEntity<String> {
        val memberId = user.id
        return try {
            cartService.clearCart(memberId)
            ResponseEntity.ok("성공적으로 제거하였습니다.")
        } catch (e: Exception) {
            ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("제거에 실패했습니다.")
        }
    }
    @GetMapping("/{cartId}")
    fun getCart(@AuthenticationPrincipal user: UserPrincipal, @PathVariable cartId: Long): ResponseEntity<out Any> {
        val memberId = user.id
        return try {
            val cart = cartService.getCart(memberId, cartId)
            if (cart.member.id != memberId) {
                ResponseEntity.status(HttpStatus.FORBIDDEN).body("You do not have permission to view this cart.")
            } else {
                ResponseEntity.ok(CartDto.from(cart))
            }
        } catch (e: Exception) {
            ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("조회할 수 없습니다.")
        }
    }

}

 

카트컨트롤러에서 저 에러메시지를 보디로 보내는건 사실 좋은 방법이 아니란 소리를 들었다.

ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("제거에 실패했습니다.")

 

이게 아니라

ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.message.toString())

 

이렇게 바꿔야 한다. 왜냐면 저렇게 BODY로 메시지를 줘버리면 어떤 상황에도 실패했으면 저 메시지를 주기 때문에 서버에러든 인증 실패든 전부 저 메시지를 주기 때문에 e.message.toString()이걸 넣어야 적절한 메시지가 자동으로 나온다.

 

 @GetMapping("/{cartId}")
    fun getCart(@AuthenticationPrincipal user: UserPrincipal, @PathVariable cartId: Long): ResponseEntity<out Any> {
        val memberId = user.id
        return try {
            val cart = cartService.getCart(memberId, cartId)
            if (cart.member.id != memberId) {
                ResponseEntity.status(HttpStatus.FORBIDDEN).body("You do not have permission to view this cart.")
            } else {
                ResponseEntity.ok(CartDto.from(cart))
            }
        } catch (e: Exception) {
            ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("조회할 수 없습니다.")
        }
    }

 

이녀석을

@GetMapping()
@Operation(summary = "카트 조회", description = "주어진 회원 ID, 카트 ID에 해당하는 카트를 조회합니다.")
fun getCarts(@AuthenticationPrincipal user: UserPrincipal): ResponseEntity<out Any> {
    val memberId = user.id
    return try{
        val carts = cartService.getCarts(memberId)
        val cartDto = carts.map { CartDto.from(it) }
        ResponseEntity.ok(cartDto)

    } catch (e: Exception) {
        ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.message.toString())
    }

}

이렇게 바꿨는데, 카트조회는 실제 앱에서도 한명이 주문한것 전부 조회해주기 때문에 cardid를 입력하는 부분을 없애고 if else도 e.message 덕분에 필요없으니 치워버린다. 

 

그리고 서비스 임플은

 

@Service
class CartServiceImpl(
    private val cartRepository: CartRepository,
    private val menuRepository: MenuRepository,
    private val storeRepository: StoreRepository,
    private val memberRepository: MemberRepository
) : CartService {
    override fun addToCart(menuId: Long, storeId: Long, memberId: Long, count: Int): Cart {
        val menu = menuRepository.findById(menuId).orElseThrow { Exception("Menu not found") }
        val store = storeRepository.findById(storeId).orElseThrow { Exception("Store not found") }
        val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }
        val cart = Cart(menu = menu, store = store, member = member, count = count)
        return cartRepository.save(cart)
    }

    override fun removeFromCart(memberId: Long, cartId: Long) {
        val cart = cartRepository.findById(cartId).orElseThrow { Exception("Cart not found") }
        if (cart.member.id != memberId) {
            throw IllegalAccessException("Not authorized to remove this cart.")
        }
        cartRepository.deleteById(cartId)
    }

    override fun clearCart(memberId: Long) {
        val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }
        val carts = cartRepository.findAllByMember(member)
        cartRepository.deleteAll(carts)
    }

    override fun getCart(memberId: Long, cartId: Long): Cart {
        val cart = cartRepository.findById(cartId).orElseThrow { Exception("Cart not found") }
        if (cart.member.id != memberId) {
            throw IllegalAccessException("Not authorized to view this cart.")
        }
        return cart
    }
}

 

이녀석을

@Service
class CartServiceImpl(
    private val cartRepository: CartRepository,
    private val menuRepository: MenuRepository,
    private val storeRepository: StoreRepository,
    private val memberRepository: MemberRepository
) : CartService {
    override fun addToCart(menuId: Long, storeId: Long, memberId: Long, count: Int): Cart {
        val menu = menuRepository.findById(menuId).orElseThrow { Exception("Menu not found") }
        val store = storeRepository.findById(storeId).orElseThrow { Exception("Store not found") }
        val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }
        val cart = Cart(menu = menu, store = store, member = member, count = count)
        return cartRepository.save(cart)
    }

    override fun removeFromCart(memberId: Long, cartId: Long) {
        val cart = cartRepository.findById(cartId).orElseThrow { Exception("Cart not found") }
        if (cart.member.id != memberId) {
            throw IllegalAccessException("Not authorized to remove this cart.")
        }
        cartRepository.deleteById(cartId)
    }

    override fun clearCart(memberId: Long) {
        val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }
        val carts = cartRepository.findAllByMember(member)
        cartRepository.deleteAll(carts)
    }

    override fun getCarts(memberId: Long): List<Cart> {
        val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }
        val carts = cartRepository.findAllByMember(member)
        return carts
    }

이렇게 만드는데, 전부조회이기 때문에 getcart를 getcarts로 하고, (memberId: Long, cartId: Long) 부분에서 cartid가 있던 이유는 특정 cart를 조회하기 위해서였는데 그 부분을 없에서 그냥 memberid만을 받아오도록 변형시켰다.

 

 

val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }:


이 줄은 memberId에 해당하는 회원을 찾는 코드다. memberRepository.findById(memberId)를 통해 해당 ID를 가진 회원을 조회하고 만약 찾는 회원이 없다면, orElseThrow 메서드에 의해 "Member not found"라는 메시지를 가진 Exception이 발생한다.


val carts = cartRepository.findAllByMember(member):


이 줄은 위에서 찾은 회원이 소유한 모든 카트를 조회하는 코드입니다. cartRepository.findAllByMember(member) 메서드는 member 객체를 인자로 받아, 해당 회원이 소유한 모든 카트를 찾아 리스트 형태로 반환합니다.
따라서, 이 두 줄의 코드를 통해 특정 회원이 소유한 모든 카트를 찾아 carts 리스트에 저장하는 작업을 수행

 

cart도 list가 됬는데 카트하나가 아니라 목록이라 그런것이다. 

 

그래서

override fun getCart(memberId: Long, cartId: Long): Cart {
        val cart = cartRepository.findById(cartId).orElseThrow { Exception("Cart not found") }
        if (cart.member.id != memberId) {
            throw IllegalAccessException("Not authorized to view this cart.")
        }
        return cart
    }
    
    
      override fun getCarts(memberId: Long): List<Cart> {
        val member = memberRepository.findById(memberId).orElseThrow { Exception("Member not found") }
        val carts = cartRepository.findAllByMember(member)
        return carts
    }

이렇게 변한다.

 

 

interface CartService {
    fun addToCart(menuId: Long, storeId: Long, memberId: Long, count: Int): Cart
    fun getCarts(memberId: Long): List<Cart>
    fun removeFromCart(memberId: Long, cartId: Long)
    fun clearCart(memberId: Long)
}

이것도 getcarts로 바꾸고 cart를 리스트로 바꿨다.

interface CartRepository : JpaRepository<Cart, Long> {
    fun findAllByMember(member: Member): List<Cart>
}

이것또한 마찬가지로 리스트로 바꿔준다.

@GetMapping("/{cartId}")
    fun getCart(@AuthenticationPrincipal user: UserPrincipal, @PathVariable cartId: Long): ResponseEntity<out Any> {
        val memberId = user.id
        return try {
            val cart = cartService.getCart(memberId, cartId)
            if (cart.member.id != memberId) {
                ResponseEntity.status(HttpStatus.FORBIDDEN).body("You do not have permission to view this cart.")
            } else {
                ResponseEntity.ok(CartDto.from(cart))
            }
        } catch (e: Exception) {
            ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("조회할 수 없습니다.")
        }
    }





@GetMapping()
@Operation(summary = "카트 조회", description = "주어진 회원 ID, 카트 ID에 해당하는 카트를 조회합니다.")
fun getCarts(@AuthenticationPrincipal user: UserPrincipal): ResponseEntity<out Any> {
    val memberId = user.id
    return try{
        val carts = cartService.getCarts(memberId)
        val cartDto = carts.map { CartDto.from(it) }
        ResponseEntity.ok(cartDto)

    } catch (e: Exception) {
        ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.message.toString())
    }

}

그리고 다시 컨트롤러로 돌아가서 여기서도 카트를 s를 붙이고 카트이티오를 map으로 받아야 한다. 이때 map를 쓰지 않으면 서비스임플의 겟카트가 작동을 안한다.