[인프런 워밍업 클럽 0기] 2주차 발자국

[인프런 워밍업 클럽 0기] 2주차 발자국

이번 주에 배운 내용

  • 스프링 컨테이너의 역할

    • 스프링 컨테이너가 시작되면 기본으로 등록되는 스프링 빈들이 있다. (JdbcTemplate)

    • 이어서 개발자가 직접 만든 클래스가 스프링 빈으로 등록된다. 이때 스프링 컨테이너가 필요한 의존성을 자동으로 주입해준다. (UserRepository를 빈으로 등록할 때 JdbcTemplate이 자동으로 DI)

    • 애플리케이션에 필요한 설정은 이제 컨테이너가 처리한다. 이를 제어의 역전이라 부른다. 개발자는 이제 비즈니스 로직에만 집중하면 된다.

  • 스프링 빈 등록 방법

    • @Configuration + @Bean 조합

    • @Component, @Controller, @Service, @Repository

    • @Primary@Qualifier를 이용하면 원하는 빈을 우선 적용할 수 있다.

  • JPA 사용하기 1 - 이론

    • SQL을 직접 작성하면 실수가 발생할 확률도 높고, 특정 DB에 종속되는 단점도 있다. 결정적으로 DB 테이블과 Java의 객체는 패러다임이 다르다. 이런 문제를 해결하기 위해 등장한 데이터 접근 기술이 JPA (Java Persistence API)이다. JPA는 객체와 관계형 데이터베이스의 테이블을 맵핑하여,

      Java

      데이터를 영구적으로 저장할 수 있도록 정해 놓은 규칙이다.

    • JPA는 인터페이스이고, 이를 구현한 대표 기술로 Hibernate가 있다. Hibernamte는 내부적으로 JDBC를 사용한다.

  • JPA 사용하기 2 - 실전

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = null;

    @Column(nullable = false, length = 20, name = "name")
    private String name;

    private Integer age;

    protected User() {
    }
    // 생략
}
public interface UserRepository extends JpaRepository<User, Long> {
}
@Service
public class UserServiceV2 {
    private final UserRepository userRepository;

    public UserServiceV2(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void saveUser(UserCreateRequest request) {
        User user = userRepository.save(new User(request.getName(), request.getAge()));
        System.out.println("id: " + user.getId());
    }
    // 생략
}
  • 스프링 트랜잭션

    • 스프링의 @Transactional은 트랜잭션 관리를 지원한다. 주의할 점으로는 org.springframework.transaction.annotation.Transactional을 붙여야 한다

      는 것이다. 다른 패키지의 @Transactional을 붙이면 정상 동작하지 않을 수 있다.

    • 데이터의 변경이 없고, 조회 기능만 있을 때는 readOnly 속성을 설정할 수 있다.

@Service
public class UserServiceV2 {
    private final UserRepository userRepository;

    public UserServiceV2(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void saveUser(UserCreateRequest request) {
        User user = userRepository.save(new User(request.getName(), request.getAge()));
        System.out.println("id: " + user.getId());
    }

    @Transactional(readOnly = true)
    public List<UserResponse> getUsers() {
        return userRepository.findAll().stream()
                .map(user -> new UserResponse(user.getId(), user.getName(), user.getAge()))
                .collect(Collectors.toList());
    }
    // 생략
}

 

미션

[6일차 - 어노테이션]

  • 링크: https://www.inflearn.com/blogs/6805

  • 레포지토리를 메모리 DB 버전과 MySQL 버전으로 나누고 교체해가며 빈으로 등록할 수 있도록 @Primary 어노테이션 선언하기

@Repository
public class FruitMemoryRepository implements FruitRepository {
    // 생략
}
@Repository
@Primary
public class FruitMySqlRepository implements FruitRepository {
    // 생략
}

 

회고

그간 MyBatis 같은 SQL Mapper만 써오다가 JPA를 이용해 애플리케이션을 개발했습니다. 기능을 추가할 때마다 SQL문도 일일이 만드는 과정이 번거로운데 JPA는 그럴 필요가 없으니 확실히 개발 생산성을 높일 수 있었습니다. 다만 새로운 유형의 기술이고 난이도도 있는 편이라 이에 적응하는 데는 시간이 걸릴 것 같습니다.

 

오늘도 함께 스터디 중인 여러분들을 존중하고 존경하며 여기서 마무리하도록 하겠습니다.

댓글을 작성해보세요.