inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 3기] 2주차 발자국

레서판다
0

[2주차]

강의수강

이론으로 알고 있었지만 실습에 들어가니 스프링은 굉장히 개념들이 잘 세분화 되어있다는 것을 느낄 수 있었습니다.

실습해보면서 배운 각 개념들에 대해 회고하며 복습해보도록 하겠습니다.


image

  1. Repository: 데이터베이스와 직접적으로 상호작용하는 계층.

     

    1. DB 쿼리에 대한 청사진을 그린다고 이해했습니다. -> 그 역할을 해주는 인터페이스가 JPA.

    2. 그 인터페이스를 받아서 @Repository가 붙인 Presentation 컴포넌트 클래스에서 직접 사용.

    interface AchievementRepository : JpaRepository<Achievement, Long> {
    
      // 문법에 맞게 JPA를 작성하면 DB에서 다음과 같은 쿼리가 작용한다.
      // select * from achievement where is_active = :isActive
      fun findAllByIsActive(isActive: Boolean): List<Achievement>
    
    }
    // 개별적인 JPA Repository의 기능을 모아서 제공하는 서비스 성격의 Repository 클래스.
    @Repository
    class PresentationRepository( // 여러 개의 Repository 인터페이스를 필드로 주입받는다.
      private val achievementRepository: AchievementRepository,
      private val experienceRepository: ExperienceRepository,
      private val introductionRepository: IntroductionRepository,
      private val linkRepository: LinkRepository,
      private val projectRepository: ProjectRepository
      private val skillRepository: SkillRepository,
    ) {
      fun getActiveAchievements(): List<Achievement> {
        return achievementRepository.findAllByIsActive(true)
      }
      ...
    }

     

  2. DTO(Data Transfer Object, 데이터 전송 객체). 쉽게 말해, 여러 개의 데이터를 하나의 상자로 포장해 옮긴다.

    1. 레이어드 계층 간에 데이터 전송을 위한 객체.

    2. 순수 데이터 이동이 목적. 거기에 불필요한 데이터 전송을 방지보안성을 높인다고 함.

    3. 사용 사례

    // Introduction Entity에는 content와 isActive 필드가 있다.
    // 그중에서 content 필드만 선택적으로 골라서 전송하는 것이다.
    data class IntroductionDTO(
      val content: String
    ) {
      constructor(introduction: Introduction) : this(
        content = introduction.content
      )
    }
    @Service
    class PresentationService(
      private val presentationRepository: PresentationRepository
    )  {
    
        // 트랜잭션을 간편하게 열고 닫을 수 있게 해줍니다.
        @Transactional(readOnly = true)
        fun getIntroductions(): List<IntroductionDTO> {
          val introductions = presentationRepository.getActiveIntroductions() // 엔터티 리스트 가져오기
          return introductions.map { introduction -> IntroductionDTO(introduction) } // DTO 변환 후 반환
        }
    }
  3. Service: 비즈니스 로직을 담당하는 계층

    1. 여러 개의 Repository에서 데이터를 가져와 비즈니스에 맞게 조합하는 계층.

    2. 단순 조합을 넘어 요구사항에 맞는 규칙을 적용하는 것도 가능.

    3. Controller와 Repository 중간에서 데이터를 제어.

       

  4. Controller: 사용자의 요청을 처리하는 계층.

     

    1. 사용자가 원하는 데이터를 조회하거나, 자신이 알고있는 데이터를 서버에 전송한다. Request.

    2. Controller에서 검증

    3. 사용자의 요청에 응답한다. 알고 있는 데이터를 보여준다던지 받아서 저장한다든지. Response.

    4. 우리 실습에선 ApiController와 ViewController가 있었다. 각각 REST Api와 웹 페이지 담당이라고 하는데 ApiController가 잘 이해가 안돼서 다시 봐야될 것 같다...

       

      @Controller
      class PresentationViewController(
        private val presentationService: PresentationService
      )  {
        @GetMapping("/")
        fun index(model: Model): String {
          // 변수 model에 Introduction 정보를 추가한다.
          val introductions = presentationService.getIntroductions()
          model.addAttribute("introductions", introductions)
      
          // 변수 model에 Link 정보를 추가한다.
          val links = presentationService.getLinks()
          model.addAttribute("links", links)
      
          return "presentation/index"
        }
      }

테스트 코드: 코드의 안정성을 보장하는 장치. 개발 시 가장 많은 시간이 소비되는 작업.


Thymeleaf 중복 처리에 대하여


힘들었던 점

워밍업 2주차

답변 0