코토리와 함께 스프링 모네 - 8. 리포지토리 레이어

개요 / 설명



코토리와 함께 스프링 모네 - 7. 서비스 에서는, 단일 모듈에 책무가 집중하는 것이 피할 수 있는 개수를 실시했습니다.
이유는 서비스 가능성, 확장 성 및 가독성이 낮은 Fat Controller가되는 것을 피하기 위해 Controller 계층에서 애플리케이션 로직을 분리하고 Service 계층을 제공했습니다.

이렇게 하면 컨트롤러 계층과 서비스 계층에서 각각 포커스하는 기능 영역을 분리할 수 있습니다. 레이어 역할 컨트롤러 레이어 요청 접수 서비스 계층 요청 접수 이외의 비즈니스 로직 처리 이제 새로 마련한 서비스 계층의 책임에 대해 생각해 봅시다. 서비스 계층의 역할은 요청 접수 이외의 비즈니스 로직을 처리하는 것입니다. 즉, 이 상태에서는 비즈니스 로직 결과의 지속성 처리도 이 Sevice 계층에서 수행하게 됩니다. 그런데 데이터의 영속화를 생각해 보면, 영속화하는 대상 영역을 Service 계층에서 의식하면, 대상 영역의 종류에 따라 설계해야 합니다. 또, 외부 영역의 종류에 의존관계가 강해져, 변경을 할 때에 영향 범위가 커져 버립니다. 예를 들어 데이터베이스를 예로 들어 Oracle DB에서 MySQL로 변경하면 방언의 차이를 의식한 설계가 필요합니다.

서비스 계층의 역할인 비즈니스 로직 처리를 고려할 때 결과의 지속성을 의식하지 않고 투명하게 처리할 수 있는 것이 설계가 단순해지고 서비스 가능성도 향상됩니다.

이 서비스 계층에서 영구 처리를 분리하는 메커니즘으로 리포지토리 계층을 제공합니다.



전제 / 환경



런타임 버전


  • Kotlin : 1.3.11
  • SpringBoot : 2.1.1.RELEASE

  • Spring Dependencies


  • Web
  • Actuator
  • JDBC
  • JPA

  • 개발 환경


  • OS : Mac
  • IDE : IntelliJ IDEA
  • Build : Gradle
  • DB : H2 Database

  • Repository 계층을 만들 때 이번에는 영구 영역으로 데이터베이스를 대상으로 합니다.
    또한 데이터베이스 유형은 단순화를 위해 H2 데이터베이스를 사용하여 내장 모드로 실행하기로 결정합니다.

    절차 / 설명



    Dependency



    데이터베이스 액세스를 위해 다음 Dependency를 build.gradle에 추가합니다.
  • org.springframework.boot:spring-boot-starter-jdbc
  • org.springframework.boot:spring-boot-starter-data-jpa

  • 또한 H2 Database를 사용하기 위해 다음 Dependency를 추가합니다.
  • com.h2database:h2

  • 데이터베이스 정의



    application.yml에 다음 H2 데이터베이스에 대한 정의를 추가합니다.
    spring:
      datasource:
        tomcat:
          test-on-borrow: true
          validation-interval: 30000
          validation-query: SELECT 1
          remove-abandoned: true
          remove-abandoned-timeout: 10000
          log-abandoned: true
          log-validation-errors: true
          max-age: 1800000
          max-active: 50
          max-idle: 10
        driver-class-name: org.h2.Driver
        url: jdbc:h2:mem:app;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE
        username: guest
        password: guest
      h2:
        console:
          enabled: true
      jpa:
        hibernate:
          ddl-auto: update
        show-sql: true
    

    리포지토리 레이어



    영속화 처리를 실시하는 레이어를 마련하기 위해서 다음의 인터페이스 정의를 실시했습니다.
    interface MessageRepository : CrudRepository<Message, String>
    

    이 인터페이스를 통해 데이터를 영속화하는 엔티티를 조작하도록 합니다.

    서비스 계층



    서비스 계층에서 주입된 Repository 계층의 인스턴스를 통해 엔티티를 조작합니다.
    @Autowired
    lateinit var repository: MessageRepository
    
    fun getMessages() : Iterable<MessageDTO> = repository.findAll().map { it -> MessageDTO(it) }
    
    fun insertMessage(messageDto: MessageDTO) = MessageDTO(
            repository.save(Message(
                                    title = messageDto.title,
                                    message = messageDto.message
            ))
    )
    

    요약 / 되돌아보기



    Controller/Service/Repository로서 ​​역할을 분리하여 설계함으로써 코드가 분리 전과 비교하여 상당히 단순해진 것을 알 수 있다고 생각합니다.
    이러한 설계를 실시해 두는 것으로 모듈의 비대화나 스파게티 코드화, 또 확장성의 저하를 억제할 수 있습니다.

    이번 소스


  • shinyay/spring-just-rest-kotlin/tree/first-repository-layer
  • 좋은 웹페이지 즐겨찾기