[인프런 워밍업 클럽 스터디 1기] BE 2주차 회고

[인프런 워밍업 클럽 스터디 1기] BE 2주차 회고

두번째 발자국

 

인프런 워밍업 클럽 스터디에 참여하여 일주일을 보낸 후 쓰는 두번째 회고록.

 



Section 3 - 역할의 분리와 스프링 컨테이너

  • 스프링 컨테이너 : 서버가 시작되면 스프링 서버 내부에 만들어지는 거대한 컨테이너

    • 이 컨테이너 안에는 (여러) 클래스가 들어가게 된다.

    • 스프링 컨테이너 안에 들어간 클래스를 스프링 빈이라 한다.

    • 스프링 빈은 (미리 작성된 프레임워크의 코드에 의해) 서버가 시작될 때 자동으로 등록되기도 하고, 코더가 @RestController 등의 어노테이션을 이용해 직접 설정하기도 한다.

    • 이때 스프링 빈 간 필요한 의존성이 자동으로 설정되고, 인스턴스화도 이루어진다.

       

  • 제어의 역전(IOC, Inversion of Control)

    • 객체를 생성하는 과정에서 스프링 컨테이너가 필요한 의존성을 자동으로 선택해서 주입해주는 방식

    • new를 이용해 어떤 구현체를 사용할지 결정하지 않고, 스프링 컨테이너가 대신 결정해주는 방식

  • 의존성 주입(DI, Dependency Injection)

    • 컨테이너가 특정 구현체를 선택해 클래스에 넣어주는 과정 (필요한 의존성을 설정해주는 과정)

  • 스프링 빈 등록 방법

    • @RestController, @Service, @Repository

    • @Configuration(클래스에 붙임), @Bean(메소드에 붙여 메소드에서 반환된 객체를 등록)

    • @Component(컨트롤러, 서비스, 레포지토리 외의 클래스를 추가적으로 등록하기 위해 사용)

  • 스프링 빈 주입받는 방법

    • 생성자를 이용해 주입(권장)

    • Setter와 @Autowired 사용

    • 필드에 직접 주입(@Autowired 사용)

    • @Qualifier

 

Section 4 - 생애 최초 JPA 사용하기

  • JPA(Java Persistence API)

     

    • 자바 진영 ORM 기술 표준

      • ORM(Object-Relational Mapping) : 데이터와 관계형 DB의 테이블을 짝짓는 방법

    • (객체와 관계형 DB를 짝지어) 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙

    • 영속성 : 서버가 재시작되도 데이터는 영구적으로 저장되는 속성

  • Hibernate

    • JPA를 구현해서 코드로 작성한 구현체

    • JPA는 단순히 API이므로, 실제 동작을 위해서는 JPA 구현체가 필요함

    • 내부적으로 JDBC를 사용

  • JPA 어노테이션

    • @Entity : 스프링이 객체와 테이블을 같은 것으로 바라봄

      • Entity : 관리되어야 하는 데이터

    • @Id : 해당 필드를 primary key로 간주

    • @GeneratedValue : primary key는 자동 생성되는 값

    • @Column : 객체의 필드와 Table의 필드를 매핑

  • JPA를 사용하려면 반드시 기본 생성자가 필요함!

  • JPA 기능

    • save : 주어지는 객체를 저장하거나 업데이트

    • findAll : 주어지는 객체가 매핑된 테이블의 모든 데이터를 가져옴

    • findById : id를 기준으로 특정한 1개의 데이터 가져옴

  • Spring Data JPA : 복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리

    • By 앞에 들어갈 수 있는 구절 정리

      • find: 1건을 가져옴. 반환 타입은 객체가 될 수도 있고 Optional<타입>이 될 수도 있음

      • findAll: 쿼리의 결과물이 N개인 경우 사용. List<타입> 반환

      • exists: 쿼리 결과가 존재하는지 확인. 반환 타입은 boolean

      • count : SQL의 결과 개수를 셈. 반환 타입은 long

    • By 뒤에 들어갈 수 있는 기능 정리

      • And / Or

      • GreaterThan : 초과

      • GreaterThanEqual : 이상

      • LessThan : 미만

      • LessThanEqual : 이하

      • Between : 사이에

      • StartsWith : ~로 시작하는

      • EndsWith : ~로 끝나는

     

  • 트랜잭션(Transaction)

    • 쪼갤 수 없는 업무의 최소 단위

       

    • 트랜잭션의 모든 로직이 성공적으로 수행되면 commit 처리되고, 예외가 발생하면 rollback 처리됨

      • 영속성 : 모든 로직을 성공시키거나, 로직들 중 하나라도 실패하면 모두 없었던 일로 하는 속

    • 트랜잭션으로 처리할 메서드 앞에 @Transactional을 붙여서 구현

       

       

  • 영속성 컨텍스트(Persistence Context)

    • 테이블과 매핑된 엔티티 객체를 관리/보관하는 역할

    • 스프링에서는 트랜잭션 수행 중 엔티티 객체를 관리/보관하는 역할을 수행

    • 트랜잭션이 수행될 때 자동으로 생성되고, 트랜잭션이 종료되면 함께 종료됨

    • 영속성 컨텍스트의 특수 기능 :

      • 변경 감지(Dirty Check) : 영속성 컨텍스트 안에서 불러와진 엔티티는 별도의 save 필요 없이 엔티티의 변경 사항을 자동으로 감지하여 저장

      • 쓰기 지연 : 모든 SQL 요청을 트랜잭션이 commit될 때 모아서 한 번만 날림

      • 1차 캐싱 : 조회된 엔티티 객체를 id를 기준으로 캐싱하여 DB 접근 횟수를 줄임

         

  •  

 

Section 5 - 책 요구사항 구현하기

 책 생성 API

  • HTTP Method : POST

  • HTTP Path : /book

  • HTTP Body (JSON) :

     

  • 결과 반환 : X (HTTP 200 OK)

대출 기능

  • HTTP Method: POST

  • HTTP Path: /book/loan

  • HTTP Body(JSON) :

  • 결과 반환 X : (HTTP 200 OK)

반납 기능

  • HTTP Method: PUT

  • HTTP Path: /book/return

  • HTTP Body(JSON) :

  • 결과 반환 X : (HTTP 200 OK)

 


 

과제

과제 4

https://shimmer-exoplanet-946.notion.site/4-0d91a864aa444cef9137e454a1c29b5d?pvs=4

과일 정보를 저장하는 API, 과일이 팔리면 과일을 팔린 상태로 변경하는 API, 과일의 이름을 받으면 해당 과일을 기준으로 팔린 금액과 팔리지 않은 금액을 조회하는 API를 작성하는 과제였다.

우선 과일을 저장할 테이블을 만들어야 했는데, 문제에서 요구되는 id, name, warehousingDate, price, status 등을 column으로 넣어주었다. 이때 status는 ENUM 타입으로 설정해 SOLD나 NOT_SOLD 두 상태 중 하나가 되도록 하였고, 디폴트 값은 NOT_SOLD로 설정해두었다.

이후 API 작성은 수업에서 배운대로 JdbcTemplatae과 직접 작성한 SQL문을 이용해 DB에 쿼리를 날리는 방식이라 크게 어렵지 않았다. 문제 3번은 배운 내용을 조금 응용해야 했는데, 과일의 이름을 받아 해당 과일이 DB에 존재하는지 확인하여 분기 처리를 하는 부분은 기존에 배운 것과 동일했지만, 해당 과일 중 팔린 과일과 필리지 않은 과일의 총액을 조회하는 부분에서 내가 원하는 기능을 수행하는 SQL 쿼리에 대한 검색을 좀 해야 했다. 우선 name이 해당 과일의 이름이고 팔린/팔리지 않은 상태의 과일들을 조회해온 다음, SUM(price)를 이용해 조회된 과일들의 price값을 합산한 후, COALESCE 함수를 이용해 SUM의 결과가 NULL이면 0을 반환하도록 했다.

 

과제 5

https://shimmer-exoplanet-946.notion.site/5-e7d1b6bae1fe44d5baf250c702270028?pvs=4

주어진 코드를 클린 코드로 리팩토링 하는 과제였다. 클린 코드가 정확히 무엇인지 알기 위해 검색을 해서 정리했다. 의미있는 변수/함수/클래스 이름을 지정하고 코드를 기능(역할)에 따라 모듈화하여 최대한 간결하면서 의도를 명확히 전달할 수 있는 코드를 짜는 것이 핵심이었다. 우선 변수와 함수의 이름을 사용 의도가 명확히 보이도록 고쳐주었고, 기존에 반복되던 코드를 for문을 이용하여 간결하게 해주었다. 또한 기존 코드는 main 함수에서 모든 기능을 수행하고 있었기 때문에 기능별로 함수를 분리해주었다.

 

두 과제 모두 무난하고 재미있게 수행할 수 있었다. 과제 4를 통해서는 수업에서 배운 것 외의 SQL 문법에 대해 공부해볼 수 있었고, 과제 5는 다른 사람들이 어떻게 리팩토링했는지 보며 내가 미처 생각하지 못한 개선점들을 볼 수 있었다.

 


 

회고

저번 주 강의는 기본적인 지식들을 쌓는 것이었는데, 이번주는 본격적인 내용으로 들어가면서 필기할 내용도 많아지고 배운 것들을 이해하는 데 더 많은 시간을 쏟아야 했다. 그래서 강의를 듣는 것도 좀 밀리고, 강의를 다 듣긴 했지만 배운 내용을 온전히 소화하지는 못했다. 다음주는 이번주 강의 내용을 다시 정리해보고, 시간을 좀 더 효율적으로 사용할 수 있도록 해야겠다. 그래도 JPA를 이용해 실제로 동작하는 도서 관리 어플리케이션을 개발해보는 과정은 정말 즐거웠다.

이번주 금요일에 코드 리팩토링에 관한 라이브 방송이 있었는데, 그걸 모르고 있다가 방송이 끝나갈 쯤에야 참여해서 아쉬움이 컸다. 과제 5를 수행하면서 클린 코드를 짜는 것이 생각보다 고려할 점이 많다는 것을 느껴서 더더욱 그랬다. 다행히 키워드와 코드를 남겨주셔서 혼자 공부해봐야 할 것 같다.

댓글을 작성해보세요.

채널톡 아이콘