상세 컨텐츠

본문 제목

[스프링2] 섹션 6. 스프링 DB 접근 기술

23-24/Spring 2

by hyom1n 2023. 10. 6. 10:00

본문

728x90

 

JPA

 

JPAORM(object-relational-mapping)으로 객체와 테이블을 매핑해주는 도구입니다. JPA는 기존의 반복 코드는 물론이고, 기본적인 SQL도 직접 만들어서 실행합니다. 또한 SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환할 수 있고, 개발 생산성을 크게 높일 수 있습니다.

 

 

JPA를 이용하려면 build.gradle 파일에 아래와 같은 라이브러리를 추가해야합니다.

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

 

JPA를 이용하려면 application.properties 파일에 아래와 같은 설정을 추가해야합니다.

// JPA 설정
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

 

위의 JPA 설정 내용은 다음과 같습니다.

show-sql : JPA가 생성하는 SQL을 출력합니다.

ddl-auto : JPA는 테이블을 자동으로 생성하는 기능을 제공하는데 ‘none’를 사용하면 해당 기능을 끕니다. ‘create’를 사용하면 엔티티 정보를 바탕으로 테이블도 직접 생성해줍니다.

 

 

JPA에 엔티티를 매핑하려면 어노테이션 @Entity를 붙입니다.

package hello.hellospring.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Member {
	
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;
	
    public Long getId() {
     	return id;
    }
    
    public void setId(Long id) {
     	this.id = id;
    }
    
    public String getName() {
     	return name;
    }
    
    public void setName(String name) {
     	this.name = name;
    }
    
}

@Id 를 통해 기본키를 매핑시킵니다.

@GeneratedValue(strategy = GenerationType.IDENTITY)를 통해 데이터 베이스가 값을 자동으로 생성합니다.

 

 

 

이제 JPA 회원 리포지토리를 생성해봅시다.

package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;

public class JpaMemberRepository implements MemberRepository {

     private final EntityManager em;
     
     public JpaMemberRepository(EntityManager em) {
     	this.em = em;
     }
     
     public Member save(Member member) {
     	em.persist(member);
     	return member;
     }
     
     public Optional<Member> findById(Long id) {
         Member member = em.find(Member.class, id);
         return Optional.ofNullable(member);
     }
     
     public Optional<Member> 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();
     }

     public List<Member> findAll() {
         return em.createQuery("select m from Member m", Member.class)
        		 .getResultList();
     }

}

JPA는 EntityManager로 모든 동작을 실행합니다. EntityManager란 엔티티를 관리하는 역할로, 스프링 부트가 자동으로 생성하기 때문에, 개발자는 인젝션만 하면 됩니다. 위 코드에서는 EntityManager가 persist, find, createQuery로 생성, 조회 및 쿼리 생성을 행합니다.

 

 

 

서비스 계층에 트랜잭션을 추가해야 합니다.

import org.springframework.transaction.annotation.Transactional

@Transactional
public class MemberService {
	...
}

스프링은 해당 클래스의 메서드를 실행할 때 트랜잭션을 시작하고, 메서드가 정상 종료되면 트랜잭션을 커밋합니다. 만약 런타임 예외가 발생하면 롤백합니다. JPA를 통한 모든 데이터 변경은 트랜잭션 안에서 실행해야 합니다.

 

 

 

 

이제 JPA를 사용하도록 스프링 설정을 변경해야 합니다.

package hello.hellospring;
import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;

@Configuration
public class SpringConfig {

     private final EntityManager em;

     public SpringConfig(EntityManager em) {
     	this.em = em;
     }

     @Bean
     public MemberService memberService() {
     	return new MemberService(memberRepository());
     }

     @Bean
     public MemberRepository memberRepository() {
    	 return new JpaMemberRepository(em);
     }

}

 

 

 

 


 

 

스프링 데이터 JPA

 

스프링 데이터 JPA를 사용하면, 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 반복해온 CRUD(Create, Read, Update, Delete) 기능도 스프링 데이터 JPA가 모두 제공합니다. 이로서 개발 코드가 확연하게 줄어들고, 개발자는 핵심 비즈니스 로직을 개발하는데 집중할 수 있습니다. 따라서 실무에서 스프링 데이터 JPA는 필수입니다.

 

 

스프링 데이터 JPA 회원 리포지토리를 아래와 같이 만듭니다.

package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

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

 

 

스프링 데이터 JPA를 이용하기 위해 스프링 설정을 변경합니다.

package hello.hellospring;
import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {
     private final MemberRepository memberRepository;
     
     public SpringConfig(MemberRepository memberRepository) {
     	this.memberRepository = memberRepository;
     }
     
     @Bean
     public MemberService memberService() {
     	return new MemberService(memberRepository);
     }
}

스프링 데이터 JPA가 SpringDataJpaMemberRepository를 스프링 빈으로 자동 등록해줍니다.

 

 

 

JpaRepository가 기본적 메서드 제공하여 개발자가 생각할 수 있는 CRUD 기능이 다 만들어져있습니다. 공통화가 불가능한 것은 findBy와 같은 방식으로 작성하면 스프링 데이터 JPA가 JPQL을 이용해 자동으로 ‘select m from Entity명 e where e. = ?’을 만들어 찾습니다. 인터페이스 이름 만으로도 개발이 끝난 것입니다. 또한 JPA는 데이터를 효율적으로 로드하고, 출력하기 위해 페이지 단위로 데이터를 분할하여 가져오는 기능인 페이징 기능을 자동으로 제공합니다.

 

 

실무에서는 JPA와 스프링 데이터 JPA를 기본으로 사용하고, 복잡한 동적 쿼리는 Querydsl이라는 라이브러리를 사용하면 됩니다. Querydsl을 사용하면 쿼리도 자바 코드로 안전하게 작성할 수 있고, 동적 쿼리도 편리하게 작성할 수 있습니다. 이 조합으로 해결하기 어려운 쿼리는 JPA가 제공하는 네이티브 쿼리를 사용하거나, 앞서 학습한 스프링 JdbcTemplate를 사용하면 됩니다.

 

 

 

 


 

 

 

Quiz

  1. JPA는 ORM으로 (  객체  )와 (  테이블  )을 매핑해주는 도구이다.
  2. JPA에 엔티티를 매핑하려면 어노테이션 (  @Entity  )를 붙인다.
  3. JPA는 엔티티를 관리하는 (  EntityManager  )로 모든 동작을 실행한다. (  EntityManager  )는 스프링 부트가 자동으로 생성한다.
  4. JPA를 통한 모든 데이터 변경은 (  트랜잭션  ) 안에서 실행해야 한다.
  5. @GeneratedValue(strategy = GenerationType.(  IDENTITY  ))를 통해 데이터 베이스가 값을 자동으로 생성한다.
  6. 스프링 데이터 JPA를 사용하면, (  인터페이스  )만으로 개발을 완료할 수 있다.
  7. JpaRepository  )에는 기본적인 CRUD 메서드를 제공한다.

 

   8. JAP를 사용하도록 스프링 설정을 하는 코드를 작성해 주세요. 주석 자리에 코드를 작성하세요.

@Configuration
public class SpringConfig {

/*
	 여기에 코드를 작성해주세요
*/

 @Bean
 public MemberService memberService() {
 return new MemberService(memberRepository());
 }

 @Bean
 public MemberRepository memberRepository() {
 return new JpaMemberRepository(em);
 }

}

 

 

 

    9. 위의 Member Entity를 참고하여 주석에 맞는 스프링 데이터 JPA 코드를  작성해주세요.

public interface SpringDataJpaMemberRepository extends JpaRepository<Member,
Long>, MemberRepository {
	
		// 1. 전체 레코드 불러오기

		// 2. 이름과 이이디를 기준으로 한 레코드 불러오기

		// 3. 아이디를 기준으로 레코드 갯수 불러오기

}

 

 

 

정답

8.

// 정답

private final EntityManager em;

public SpringConfig(EntityManager em) {
 this.em = em;
 }

 

 

9.

// 1
List<Member> findAll();

// 2
Optional<Member> findByNameAndId(String name, Long Id);

// 3
Long countById(Long Id);

 

 


 

[출처] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 (기술 섹션 6. 스프링 DB 접근 기술), 김영한 https://inf.run/WzVy

[출처] [JPA] 페이징과 정렬에 대해 알아보자. https://hstory0208.tistory.com/entry/Spring-Data-JPA-페이징과-정렬에-대해-알아보자

 

 

 

 

Corner Spring 2

Editor : 이조

728x90

관련글 더보기