프레임워크/Spring

[인프런][스프링 입문] 21~24강

pythaac 2022. 3. 8. 22:39
  • 스프링 통합 테스트
  • 스프링 JdbcTemplate
  • JPA
  • 스프링 데이터 JPA

 

<스프링 입문 강의 - 21강 스프링 통합 테스트>

* Spring boot 테스트 작성법

- [애노테이션] @SpringBootTest, @Transactional 애노테이션이 추가되어야 함

- [참고] 테스트에서 정도는 필드 @Autowired를 사용해도 된다 (편하다)

 

* @SpringBootTest

- 스프링 컨테이너와 테스트를 함께 실행

- 진짜 스프링을 띄워서 테스트를 함

 

* @Transactional

- DB 연동 테스트시 테스트 전 상태로 rollback해줌

- afterEach가 필요 없음!

- [이유] 트랜잭션을 commit하기 전에 rollback해버림

 

* 단위 테스트는 필요 없는가?

- 스프링 컨테이너를 실행하는 테스트를 통합 테스트라고 함

- 통합 테스트보다 순수 자바를 이용한 단위 테스트 속도가 훨씬 빠름

- 단위 테스트가 더 좋은(?) 테스트일 확률이 높다고 함

- 단위 단위 쪼개서 하는 테스트가 좋은 테스트라고 말씀하시는 듯

 


<스프링 입문 강의 - 22강 스프링 JdbcTemplate>

* JdbcTemplate

- 설정(bulid.gradle)은 순수 Jdbc 설정과 같음

- JDBC API의 반복 코드를 제거

- SQL은 직접 작성해야함

- 디자인 패턴 중 템플릿 패턴을 따라서 JdbcTemplate이라고 함

 

* RowMapper

- 객체에 맵핑시키는 함수를 직접 callback으로 던져줌

 


<스프링 입문 강의 - 23강 JPA>

* JPA

- 기본적인 SQL쿼리도 JPA가 직접 만들어서 실행해줌

- SQL/데이터 중심 설계에서 객체 중심 설계로 패러다임을 전환할 수 있음

- 따라서 개발 생산성을 크게 높일 수 있음

 

* 초기 세팅

- build.gradle에 다음 내용 추가

1) implementation org.springframework.boot:spring-boot-starter-data-jpa

- application.properties에 다음 내용 추가

1) spring.jpa.show-sql=true
jpa가 날리는 sql을 볼 수 있음

2) spring.jpa.hibernate.ddl-auto=none

객체를 보고 자동 테이블 생성 (none으로 생성하지 않도록 설정함)

* ORM (Object Relational Mapping)

- 객체와 Relational DB table을 맵핑한다는 의미

 

* Hibernate

- JPA 표준의 구현체 중 하나

- 대부분 사용

 

* @Entity

- JPA가 관리하는 엔티티

 

* @Id

- PK 설정

 

* @GeneratedValue(strategy = GenerationType.IDENTITY)

- identity strategy : DB가 자동으로 id를 생성해줌

- identity 전략을 설정

 

* @Column(name = "name")

- name이라는 컬럼에 맵핑

 

* EntityManager

- JPA는 모든 것을 EntityManager로 동작함

- JPA를 사용하기 위해서는 EntityManager를 주입 받아야함

- persist : 영구 저장한다는 의미

public class JpaMemberRepository implements MemberRepository{

	private final EntityManager em;
    
    public JpaMemberRepository(EntityManager em){
		this.em = em;
    }
    
    @Override
    public Member save(Member member){
		em.persist(member);
        return member;
    }
    
    @Override
    public Optional<Member> findById(Long id){
    	Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);   
    }
    
    @Override
    public Optional<Memer> findByName(String name) {
    	List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
        		.setParameter("name", name)
				.getResultList();
        
        return result.stream().findAny();
    }
    
    @Override
    public List<member> findAll() {
    	return em.create("select m from Member m", Member.class)
        		.getResultList();

 

* @transactional

- JPA는 모든 변경이 트랜잭션 안에서 실행되어야 함

 


<스프링 입문 강의 - 24 스프링 데이터 JPA>

* 스프링 데이터 JPA

- 인터페이스만으로 개발을 완료할 수 있음

- 기본 CRUD 기능을 모두 제공

- 핵심 비즈니스 로직 개발에 집중할 수 있음

 

* JPA를 학습하고 스프링 데이터 JPA를 학습하라

- 스프링 데이터 JPA는 JPA를 편리하게 해주는 도구일 뿐임

 

* 초기 설정

- JPA 설정과 같음

 

* 사용 방법

public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
	
    @Override
    Optional<Member> findByName(String name);
}

- 스프링 데이터 JPA가 JpaRepository를 상속 받으면 구현체를 자동으로 만들어서 빈으로 등록 (Proxy 기술을 사용)

- [충격] 인터페이스는 다중 상속이 된다..... 왜 이걸 몰랐을까 ㅠㅠ

 

* JpaRepository 계층 구조

- 무작정 따라하기로 CrudRepository를 사용했었음

- PagingAndSortingRepository : 정렬과 페이징(페이지를 나누는 것, Pagination) 기능을 제공

 

* Querydsl

- JPA와 스프링 데이터 JPA를 기본으로 사용하고,

- 복잡한 동적 쿼리는 Querydls 사용