![[인프런 워밍업 클럽 스터디 1기] BE 2주차 <두 번째 회고록>](https://cdn.inflearn.com/public/files/blogs/e3f2c45d-eda4-47ce-93f8-f03eb451c6f4/333476.png)
[인프런 워밍업 클럽 스터디 1기] BE 2주차 <두 번째 회고록>
강의 요약
Day 7 <스프링 컨테이너의 의미와 사용 방법>
UserController와 스프링 컨테이너
@RestController
UserController 클래스를 스프링 빈으로 등록시킴
스프링 빈
서버가 시작되면 스프링 서버 내부에 거대한 컨테이너를 만들게 되는데 이 컨테이너 안에는 여러 클래스가 들어가게 됨
이때 다양한 정보도 함께 들어 있고 인스턴스화도 이루어짐
JdbcTemplate도 스프링 빈에 등록되어 있음
미리 설정해 둔 의존성(Dependency)가 등록해 주고 있었음
서버가 시작되면 일어나는 일
스프링 컨테이너(클래스 저장소) 시작
기본적으로 많은 스프링 빈 등록
우리가 설정한 스프링 빈 등록
이때 필요한 의존성 자동 설정
UserRepository는 JdbcTemplate을 가져오지 못할까?
JdbcTemplate을 가져오려면 UserRepository가 스프링 빈이어야 하는데 UserRepository는 스프링 빈이 아님
UserRepository를 스프링 빈으로 등록하면 바로 가져올 수 있음
UserService와 UserRepository를 스프링 빈으로 등록
UserService -> @Service 어노테이션 추가
UserRepository -> @Repository 어노테이션 추가
이제 3개의 클래스가 서버를 시작할 때 따르는 순서
가장 기본적인 스프링 빈 등록
JdbcTemplate에 의존하는 UserRepository가 스프링 빈으로 등록
UserRepository를 의존하는 UserService가 스프링 빈으로 등록
UserService를 의존하는 UserController가 스프링 빈으로 등록
스프링 컨테이너를 왜 사용할까?
Repository를 다른 Class로 바꾸더라도 BookService를 변경하지 않는 방법
Java의 Interface 활용
@Primary 어노테이션이 붙어 있는 Repository를 우선 사용
스프링 컨테이너
의존성 주입(DI, Dependency Injection): 컨테이너가 선택해 BookService에 넣어 주는 과정
제어의 역전(IoC, Inversion of Control) 방식
스프링 컨테이너를 다루는 방법
스프링 빈 등록하는 방법
@Configuration
클래스에 붙이는 어노테이션
@Bean을 사용할 때 함께 사용해 주어야 함
@Bean
메소드에 붙이는 어노테이션
메소드에 반환되는 객체를 스프링 빈에 등록
언제 @Service, @Repository를 사용할까?
개발자가 직접 만든 클래스를 스프링 빈으로 등록할 때
언제 @Configuration, @Bean을 사용할까?
외부 라이브러리, 프레임워크에서 만든 클래스를 등록할 때
@Component
주어진 클래스를 '컴포넌트'로 간주
이 클래슬들은 스프링 서버가 뜰 때 자동으로 감지
@Component 덕분에 우리가 사용했던 어노테이션이 자동감지
Controller, Service, Repository가 모두 아니고 개발자가 직접 작성한 클래스를 스프링 빈으로 등록할 때 사용
스프링 빈 주입받는 방법
생성자를 이용해 주입받는 방식 (권장)
@Autowired 생략 가능
Setter와 @Autowired 사용
누군가 setter를 사용하면 오작동할 가능성 있음
필드에 직접 @Autowired 사용
테스트를 어렵게 만드는 요인
@Qualifier
@Primary vs @Qualifier
사용하는 쪽이 직접 적은 @Qualifier이 우선적
Day 8 <Spring Data JPA를 사용한 데이터베이스 조작>
문자열 SQL을 직접 사용하는 것이 너무 어렵다
SQL을 직접 작성하면 아쉬운 점
문자열을 작성하기 때문에 실수할 수 있고 실수를 인지하는 시점이 느림
컴파일 시점에 발견되지 않고 런타임 시점에 발견됨
특정 데이터베이스에 종속적이게 됨
반복 작업이 많아지며 테이블을 하나 만들 때마다 CRUD 쿼리가 항상 필요
데이터베이스의 테이블과 객체는 패러다임이 다름
JPA(Java Persistence API)
객체와 관계형 DB의 테이블을 짝지어 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙
Hibernate: 말로 되어 있는 규칙을 코드로 구현한 것
Hibernate(구현체)이 JPA를 구현
내부적으로 JDBC 사용
유저 테이블에 대응되는 Entity Class 만들기
Java 객체 <-> MySQL Table 매핑
JPA 어노테이션
@Entity: Spring이 User 객체와 user 테이블을 같은 것으로 바라봄
@Id: 이 필드를 primary key로 간주
@GeneratedValue: primary key는 자동 생성되는 값임
@Column: 객체의 필드와 Table 필드 매핑
JPA를 사용하기 위해서는 기본 생성자가 반드시 필요
JPA 추가 설정
ddl_auto: 스프링이 시작할 때 DB에 있는 테이블을 어떻게 처리할지 (create, create-drop, update, validate, none)
format_sql: SQL을 보여 줄 때 예쁘게 포맷팅 할 것인가
show_sql: JPA를 사용해 DB에 SQL을 날릴 때 SQL을 보여 줄 것인가
dialect: 조금씩 다른 SQL을 수정해 줌
Spring Data JPA를 이용해 자동으로 쿼리 날리기
JPA 기능 정리
save: 주어지는 객체를 저장하거나 업데이트
findAll: 주어지는 객체가 매핑된 테이블의 모든 데이터 가져옴
findById: id를 기준으로 특정한 1개의 데이터 가져옴
Spring Data JPA
복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리
Spring Data JPA를 이용해 다양한 쿼리 작성하기
다양한 Spring Data JPA 쿼리
By 앞에 들어갈 수 있는 구절 정리
find: 1건을 가져옴, 반환 타입은 객체가 될 수도 있고 Optional<타입>이 될 수도 있음
findAll: 쿼리의 결과물이 N개인 경우 사용, List<타입> 반환
exists: 쿼리 결과가 존재하는지 확인, 반환 타입은 boolean
By 뒤에 들어갈 수 있는 기능 정리
And / Or 조합 가능
GreaterThan: 초과
GreaterThanEqual: 이상
LessThan: 미만
LessThanEqual: 이하
Between: 사이에
StartsWith: ~로 시작하는
EndsWith: ~로 끝나는
Day 9 <트랜잭션과 영속성 컨텍스트>
트랜잭션 이론편
트랜잭션: 쪼갤 수 없는 업무의 최소 단위
트랜잭션 시작: start transaction;
트랜잭션 정상 종료: commit; (SQL 반영)
트랜잭션 실패 처리: rollback; (SQL 미반영)
영속성: 모든 SQL을 성공시키거나 하나라도 실패하면 모두 실패시키는 속성
트랜잭션 적용과 영속성 컨텍스트
@Transactional:
스프링에서 트랜잭션 적용할 때 사용
주의사항:
IOException과 같은 Checked Exception은 롤백이 일어나지 않음
영속성 컨텍스트:
테이블과 매핑된 Entity 객체를 관리 및 보관하는 역할
영속성 컨텍스트의 특수 능력
변경 감지(Dirty Check): 영속성 컨텍스트 안에서 불러와진 Entity는 명시적으로 save하지 않더라도 변경을 감지해 자동으로 저장
쓰기 지연: DB의 INSERT / UPDATE / DELETE SQL을 바로 날리는 것이 아니라 트랜잭션이 commit 될 때 모아서 한 번만 날림
1차 캐싱: ID를 기준으로 Entity를 기억함, 이렇게 캐싱된 객체는 완전히 동일
Day 10 <조금 더 복잡한 기능을 API로 구성하기>
책 생성 API 개발하기
HTTP Method: POST
HTTP Path: /book
HTTP Body (JSON)
결과 반환 X (Only HTTP 상태 200)
대출 기능 개발하기
HTTP Method: POST
HTTP Path: /book/loan
HTTP Body (JSON)
결과 반환 X (Only HTTP 상태 200)
반납 기능 개발하기
HTTP Method: PUT
HTTP Path: /book/return
HTTP Body (JSON)
결과 반환 X (Only HTTP 상태 200)
회고
1주차 스터디에 이어서 더 딥한 내용을 접하고 직접 사용해 볼 수 있었습니다. 아직 헷갈리는 부분이 있기는 하지만 강의를 반복해서 듣고 부족한 개념을 채워 넣는다면 배포까지 잘 마무리할 수 있을 것 같습니다. 미니 프로젝트까지 잘 완성하는 것이 목표입니다.
댓글을 작성해보세요.