인프런 워밍업 클럽 스터디 1기 BE 두번째 발자국

인프런 워밍업 클럽 스터디 1기 BE 두번째 발자국

학습 내용

스프링 컨테이너의 의미와 사용 방법

스프링 빈

스프링은 스프링 서버 내부에 거대한 컨테이너를 만들고

이 컨테이너 안에는 여러 클래스가 들어간다.

이때 다양한 정보도 함께 들어 있고 인스턴스화도 이루어짐

JdbcTemplate도 스프링 빈에 등록되어 있어서 의존성을 등록해준다.

서버가 시작되면 일어나는 일

  • 스프링 컨테이너 시작

  • 기본적인 스프링 빈 등록

  • 우리가 설정한 스프링 빈 등록

  • 이때 필요한 의존성 자동 설정

UserRepository는 JdbcTemplate을 가져오지 못한이유

UserRepository가 스프링 빈이어야 하는데 UserRepository는 스프링 빈이 아니기 때문에

UserRepository를 스프링 빈으로 등록하면 가져올 수 있다.

@Service와 @Repository 어노테이션을 사용해 스프링 빈으로 등록

스프링 컨테이너를 다루는 방법

스프링 빈 등록하는 방법

@Configuration

  • 클래스에 붙이는 어노테이션

  • @Bean을 사용할 때 함께 사용해 주어야 함

@Bean

  • 메소드에 붙이는 어노테이션

  • 메소드에 반환되는 객체를 스프링 빈에 등록

@Component

  • 주어진 클래스를 컴포넌트로 간주

  • 이 클래스들은 스프링 서버가 뜰 때 자동으로 감지

  • @Component 덕분에 우리가 사용했던 어노테이션이 자동감지

  • Controller, Service, Repository가 모두 아니고 개발자가 직접 작성한 클래스를 스프링 빈으로 등록할 때 사용

스프링 빈 주입받는 방법

  • 생성자를 이용해 주입받는 방식

    • @Autowired 생략 가능

  • Setter와 @Autowired 사용

    • 누군가 setter를 사용하면 오작동할 가능성 있음

  • 필드에 직접 @Autowired 사용

    • 테스트를 어렵게 만드는 요인

  • @Qualifier

    • @Primary vs @Qualifier

    • 사용하는 쪽이 직접 적은 @Qualifier이 우선적

Spring Data JPA를 사용한 데이터베이스 조작

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를 이용해 다양한 쿼리 작성하기

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

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

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

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

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

    • And / Or 조합 가능

    • GreaterThan: 초과

    • GreaterThanEqual: 이상

    • LessThan: 미만

    • LessThanEqual: 이하

    • Between: 사이에

    • StartsWith: ~로 시작하는

    • EndsWith: ~로 끝나는

트랜잭션과 영속성 컨텍스트

트랜잭션

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

  • 트랜잭션 시작: start transaction;

  • 트랜잭션 정상 종료: commit; (SQL 반영)

  • 트랜잭션 실패 처리: rollback; (SQL 미반영)

  • 영속성: 모든 SQL을 성공시키거나 하나라도 실패하면 모두 실패시키는 속성

트랜잭션 적용과 영속성 컨텍스트

@Transactional

  • 스프링에서 트랜잭션 적용할 때 사용

  • IOException과 같은 Checked Exception은 롤백이 일어나지 않음

영속성 컨텍스트

  • 테이블과 매핑된 Entity 객체를 관리 및 보관하는 역할

  • 변경 감지(Dirty Check)

    • 영속성 컨텍스트 안에서 불러와진 Entity는 명시적으로 save하지 않더라도 변경을 감지해 자동으로 저장

  • 쓰기 지연

    • DB의 INSERT / UPDATE / DELETE 문을 바로 날리는 것이 아니라 트랜잭션이 commit 될 때 한번에 날림

  • 1차 캐싱

    • ID를 기준으로 Entity를 기억

    • 캐싱된 객체는 동일한 객체

댓글을 작성해보세요.