• [인프런 김영한 로드맵1]스프링 입문 강의 정리(3)

    2022. 1. 1.

    by. 웰시코더

    반응형

    -인프런 김영한 강사님의 스프링 입문 강의 핵심 위주로 정리한다.
    -모든 소스는 깃허브에서 관리한다.(https://github.com/coderahn/Spring-Lecture1)


    7.스프링 DB 접근 기술

     

    메모리DB가 아닌 H2 DB를 사용하여 순수JDBC, JdbcTemplate, JPA, Spring JPA 순으로 DB접근 기술을 학습한다. 

     

    1)H2 데이터베이스 설치

    DB는 H2로 사용한다. H2는 자바기반 RDMBS이며 저용량이고 브라우저 콘솔을 지원한다. 테스트 DB로 많이 사용된다고 한다.

    H2 실행 후, member테이블을 생성한다. 

    • member의 id는 자바에서 Long타입이었다. 컬럼타입을 bigint로 지정한다. bigint는 MySQL에 있는 타입이다.
    • id bigint generated by default as identity에서 generated...as identity는 들어온 값이 없는 경우 자동으로 시퀀스 생성을 해준다. 오라클에도 있는 기능이다.

     

    2)순수 JDBC

    기존 메모리방식DB가 아닌 JDBC방식을 사용하도록 바꾼다. 단순히 JDBC API로만 코딩하여 사용하며 과거에 많이 사용한 방식이다. 

    DB방식으로 바꾸려면 다음과 같은 기본 작업이 필요하다.

    • gradle을 이용해 JDBC, H2(DB) 라이브러리 추가
    • application.properties에 스프링부트 DB연결 설정 추가
      • spring.datasource.url, spring.datasource.driver-class-name 등 
      • 자바 설정참고파일(SpringConfig)에 새로 사용할 리포지토리(JdbcMemberRepository)를 자바빈으로 받을 수 있게 변경

     

    아래는 회원을 저장하는 save()를 JDBC로만 구현한 화면이다.

     

    순수 JDBC로 구현한 회원관리 저장 메소드

    흐름은 sql을 만들고 커넥션을 열어주고 DB에 접근하여 데이터를 save하고 pk를 가져온 후, 커넥션을 닫아준다. SELECT, DELETE 등 코드 흐름이 비슷하며 코드가 길기 때문에 최근에는 잘 안 쓴다고 한다.

     

    3)스프링 통합 테스트

    스프링 컨테이너, DB까지 연결한 테스트를 진행한다. 새로 만든 테스트 클래스 파일 상단에 다음과 같은 어노테이션을 추가한다.

    • @SpringBootTest : 스프링 컨테이너와 테스트를 함께 실행한다(설정 파일 등 참고하여 런타임 의존성, DB연결 등 모두 사용)
    • @Transactional : 이 어노테이션을 붙이면 TEST로 Insert 등을 실행해도 최종적으로 모두 롤백하여 실데이터에 영향이 안 갈수 있도록 해준다. 다음 테스트에 영향을 주지 않는다.

     

    4)스프링 JdbcTemplate

    순수 JDBC에서 반복된 코드를 제거해주는 장점이 있다.

     

    findAll() jdbcTemplate 방식 구현

     

    5)JPA(Java Persistence API)

    • 기존 반복 코드 뿐만 아니라, 기본적인 SQL도 없이 JPA가 직접 만들어서 실행
    • SQL과 데이터 중심 설계에서 객체 중심 설계로 패러다임 전환 가능
    • JPA는 자파 표준 인터페이스이며 이를 벤더별로 구현한 구현체가 Hibernate(주로 사용)

     

    JPA를 사용하려면 build.gradle에서 ...starter-jdbc가 아니라 ...starter-data-jpa를 implementation하면 된다. 또한 application.properties에 다음 설정을 추가한다. 

    spring.jpa.show-sql=true //JPA가 생성하는 SQL를 출력한다.
    spring.jpa.hibernate.ddl-auto=none //ddl-auto를 none으로 설정하면 테이블을 자동생성하지 않는다. create로 설정하면 JPA구동시 테이블을 자동생성한다.

     

    그리고 MemberRepository를 구현한 JpaMemberRepository를 만든다.

     

     

    EntityManager를 사용하여 crud처리를 기본적으로 한다. 또한 findByName나 findAll을 사용할 때 JPQL을 사용하는데 JPQL은 SQL을 테이블대상이 아닌 객체(Entity)대상으로 한다. 다음과 같다.

     

     

    마지막으로 JPA사용시 Service 클래스 상단에 @Transactional을 붙여줘야 한다. JPA를 통한 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다.

     

    6)스프링 데이터 JPA

    스프링 데이터 JPA를 사용하면 리포지토리 구현 클래스 없이 인터페이스만으로 개발을 할 수 있다. CRUD의 기본적 기능을 스프링 데이터 JPA가 모두 제공한다. 다음과 같이 Repository 인터페이스를 만들 수 있다.

     

    위의 코드 이미지에서 보듯이, SpringDataJpaMemberRepository 인터페이스가 다른 인터페이스를 상속한다. 인터페이스가 인터페이스를 상속할 때는 implements가 아닌 extends를 사용하며 다중상속이 가능하다. 그리고 저렇게 JpaRepository를 상속하면 자동으로 스프링컨테이너가 MemberRepository 구현체를 빈으로 만들어 관리한다고 한다.

     

    그리고 스프링 빈 설정관계를 만들어주는 SpringConfig는 다음과 같이 바꾼다.

     

    MemberRepository 구현체를 스프링컨테이너가 관리하고 있기 때문에 이미지처럼 생성자방식으로 의존성주입을 해줄 수 있다. 생성자가 1개이기 때문에 굳이 @Autowired를 붙일 필요가 없다.

    이후 통합테스트를 돌려보면 정상적으로 성공하는 것을 확인하였다.

     

    스프링데이터 JPA의 기본 인터페이스인 JpaRepository 인터페이스는 Paging관련 인터페이스, CRUD관련인터페이스를 다중상속하고 있다. 그렇기 때문에 기본적인 CRUD 등을 쿼리나 구현메소드 없이 바로 동작하게 해준다. 복잡한 동적쿼리는 이후 QueryDsl을 사용한다고 한다.

     

    또한 기본적으로 제공하는 메소드 이외에 비지니스 로직별로 다른 메소드가 있는 경우 표기룰만 맞춰준다면 리플렉션 기술로 알아서 SQL을 만들어준다. 위 이미지의 findByName은 사실 기본적인 스프링데이터JPA 제공 메소드가 아니다. 리플렉션 기술로 findByName은 다음처럼 해석되어 돌아간다.

    select m from member m where m.name = ?

    마지막으로 JPA만으로 꼭 모든 것을 할 필요 없게하도록 기본적인 SQL쿼리 방식을 사용할 수 있게 열어놨다고 한다. 그러나 대부분의 데이터접근 메소드는 JPA로 구현이 가능하다고 한다.

     

    반응형

    댓글