1. 이전 포스팅

 

https://growingsaja.tistory.com/972

 

 

 

 

 

2. 현 상황 확인 및 목표

 

Coffee의 경우 User와 달리, Service 없이 Controller에서 Repository를 바로 불러와 사용하고 있습니다. 그래서 User처럼 Controller -> Service -> Repository 구조로 소스코드를 수정해 적용해줍니다.

 

 

 

 

 

3. Entiry - Repository - Service - Controller

 

// vim Coffee.kt

package com.example.practicekopring.entities

// Jakarta Persistence API(JPA)에서 필요한 어노테이션들을 가져옵니다.
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id

// @Entity 어노테이션은 이 클래스가 JPA 엔터티임을 나타냅니다.
@Entity
// Coffee 엔티티 클래스를 정의합니다.
data class Coffee (
    // @Id 어노테이션은 이 필드가 엔터티의 기본 키(primary key)임을 나타냅니다.
    @Id
    // @GeneratedValue 어노테이션은 기본 키의 생성 전략을 나타내며, IDENTITY 전략은 데이터베이스가 자동으로 기본 키 값을 생성하도록 지시합니다.
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    // "id" 필드는 Coffee 엔터티의 기본 키이며, 기본값은 0입니다.
    var id: Int = 0,
    val name: String,
)

 

 

 

 

 

4. Entiry - Repository - Service - Controller

 

// vim CoffeeRepository.kt

package com.example.practicekopring.repositories

import com.example.practicekopring.entities.Coffee
import org.springframework.data.jpa.repository.Query
// Spring Data JPA에서 사용하는 쿼리 어노테이션을 가져옵니다.
import org.springframework.data.jpa.repository.JpaRepository
// Spring Data Repository의 기본 기능을 제공하는 CrudRepository를 가져옵니다.

// CrudRepository에서는 findAll(), findById(), save(), deleteById() 등의 크루드(기본 CRUD) 작업을 자동으로 지원하므로 이를 활용할 수 있습니다.
interface CoffeeRepository : JpaRepository<Coffee, Int> {
    // CoffeeRepository 인터페이스를 정의하며, Coffee 엔터티를 조작할 수 있는 메서드를 정의합니다.

    @Query("SELECT MAX(c.id) FROM Coffee c")
    // @Query 어노테이션은 사용자 정의 JPQL(Jakarta Persistence Query Language) 쿼리를 정의합니다.
    fun findMaxId(): Int?
    // "findMaxId" 메서드는 Coffee 엔터티의 최대 ID 값을 찾는 쿼리를 실행하고, 결과를 Int로 반환합니다. 결과가 없을 경우 nullable한 Int를 반환합니다.
}

 

 

 

 

 

5. Entiry - Repository - Service - Controller

 

// vim services/CoffeeService.kt

package com.example.practicekopring.services

import com.example.practicekopring.entities.Coffee
import com.example.practicekopring.repositories.CoffeeRepository
import org.springframework.stereotype.Service
import java.util.*

@Service
class CoffeeService(private val coffeeRepository: CoffeeRepository) {

    fun getAllCoffees(): MutableIterable<Coffee> {
        return coffeeRepository.findAll()
    }

    fun getCoffeeById(id: Int): Optional<Coffee> {
        return coffeeRepository.findById(id)
    }

    fun createCoffee(coffee: Coffee): Coffee {
        return coffeeRepository.save(coffee)
    }

    fun updateCoffee(id: Int, updatedCoffee: Coffee): Optional<Coffee> {
        val existingCoffee = coffeeRepository.findById(id)
        if (existingCoffee.isPresent) {
            val coffeeToUpdate = existingCoffee.get().copy(name = updatedCoffee.name)
            coffeeRepository.save(coffeeToUpdate)
            return Optional.of(coffeeToUpdate)
        }
        return Optional.empty()
    }

    fun deleteCoffee(id: Int) {
        coffeeRepository.deleteById(id)
    }
}

 

 

 

 

 

6. Entiry - Repository - Service - Controller

 

// vim controllers/CoffeeController.kt

package com.example.practicekopring.controllers

import com.example.practicekopring.entities.Coffee
import com.example.practicekopring.services.CoffeeService
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/api/coffees")
class CoffeeController(private val coffeeService: CoffeeService) {

    @GetMapping
    fun getAllCoffees(): MutableIterable<Coffee> {
        return coffeeService.getAllCoffees()
    }

    @GetMapping("/{id}")
    fun getCoffeeById(@PathVariable id: Int): ResponseEntity<Coffee> {
        val coffee = coffeeService.getCoffeeById(id)
        return if (coffee.isPresent) {
            ResponseEntity(coffee.get(), HttpStatus.OK)
        } else {
            ResponseEntity(HttpStatus.NOT_FOUND)
        }
    }

    @PostMapping
    fun createCoffee(@RequestBody coffee: Coffee): ResponseEntity<Coffee> {
        val createdCoffee = coffeeService.createCoffee(coffee)
        return ResponseEntity(createdCoffee, HttpStatus.CREATED)
    }

    @PutMapping("/{id}")
    fun updateCoffee(@PathVariable id: Int, @RequestBody updatedCoffee: Coffee): ResponseEntity<Coffee> {
        val updatedCoffeeOptional = coffeeService.updateCoffee(id, updatedCoffee)
        return if (updatedCoffeeOptional.isPresent) {
            ResponseEntity(updatedCoffeeOptional.get(), HttpStatus.OK)
        } else {
            ResponseEntity(HttpStatus.NOT_FOUND)
        }
    }

    @DeleteMapping("/{id}")
    fun deleteCoffee(@PathVariable id: Int): ResponseEntity<Unit> {
        coffeeService.deleteCoffee(id)
        return ResponseEntity(HttpStatus.NO_CONTENT)
    }
}

 

 

 

 

+ Recent posts