상세 컨텐츠

본문 제목

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

23-24/Spring 3

by recoday 2023. 10. 6. 10:00

본문

728x90

JPA

JPA

  • ORM(Object-Relational-Mapping) 으로 객체와 테이블을 매핑해주는 인터페이스 모음
  • 기존의 반복 코드를 줄이고, 기본적인 SQL 쿼리문도 직접 만들어서 실행해 코드를 간결하게 작성함
  •  SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환하여 개발 생산성을 크게 높임
ORM(Object-Relational-Mapping)
우리가 일반적으로 알고 있는 애플리케이션 Class와 RDB(Relational DataBase)의 테이블을 
매핑(연결)한다는 뜻이며, 기술적으로는 어플리케이션의 객체를 RDB 테이블에 자동으로 영속화 해주는 것이라고 보면된다.

 

JPA 사용을 위한 설정

1. build.gradle 파일에 아래와 같은 라이브러리를 추가

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

 

2.  application.properties 파일에 설정을 추가

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

 

  • show-sql : JPA가 생성하는 SQL을 확인하는 용도
  • ddl-auto : JPA는 테이블을 자동으로 생성하는 기능을 제공
    • ‘none’ : 해당 기능을 끄는 모드
    •  ‘create’ : 엔티티 정보를 바탕으로 테이블도 직접 생성해주는 모드
    • 이 외에도 create-drop, update, validate 3가지 옵션이 더 있음

 

JPA 사용 

1. Member 객체 수정

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;
    }
    
}
  • JPA에 엔티티를 매핑을 위해 어노테이션 @Entity, @Id, @GeneratedValue 추가
  • @Id로 데이터베이스의 기본키를 매핑함
  • @GeneratedValue(strategy = GenerationType.IDENTITY)로 데이터베이스가 ID 값을 자동으로 생성하도록 함

 

2. JPA 회원 리포지토리를 생성

// MemberRepository.java

public class JpaMemberRepository implements MemberRepository {

     // JPA는 EntityManager가 직접 엔터티를 관리하므로 추가
     // EntityManager가 persist, find, createQuery로 생성, 조회 및 쿼리 생성함
     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();
     }

}

 

3. 서비스 계층에 트랜잭션을 추가

import org.springframework.transaction.annotation.Transactional

@Transactional
public class MemberService {
	...
}
  • 스프링은 메서드 실행시 트랜젝션을 시작하고 종료시 트랜젝션을 커밋함
  • 따라서 JPA를 통한 모든 데이터 변경은 트랜잭션 안에서 실행해야함
  • @Transactional 어노테이션으로 이를 해결

4. JPA를 사용하도록 스프링 설정을 변경

// SpringConfig.java

@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

  • 반복되는 SQL의 CRUD(Create, Read, Update, Delete) 기능을 스프링 데이터 JPA가 모두 제공
  • 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료하는 모듈
  • 개발자는 핵심 비즈니스 로직을 개발하는데 집중하도록 도움

 

스프링 데이터 JPA 사용 

1. 스프링 데이터 JPA 회원 리포지토리 만들기

public interface SpringDataJpaMemberRepository extends JpaRepository<Member,Long>, MemberRepository {
 	Optional<Member> findByName(String name);
}
  • 기존 함수들은 스프링 데이터 JPA의 인터페이스에서 제공되어 따로 작성할 필요가 없음
    • 각종 CRUD 함수는 인터페이스에서 제공됨
  • 제공하지 않는 함수의 경우 findByName처럼 특정한 규칙을 따르기만 하면 쿼리문을 자동으로 만들어 함수를 생성해줌

 

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

// SpringConfig.java
@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를 스프링 빈으로 자동 등록

 


Quiz

  1. JPA는 ORM으로 (  객체  )와 (  테이블  )을 매핑해주는 ( 인터페이스 )입니다.
  2. JPA는 기본적인 ( SQL 쿼리문 )을 직접 만들어줘서 코드가 간결해지고, 데이터 중심 설계에서 ( 객체 ) 중심의 서례로 패러다임을 전환했다는 데에서 의의를 지닌다.
  3. JPA에 엔티티를 매핑하기 위해 어노테이션 (  @Entity  )를 붙인다.
  4. JPA는 직접 엔티티를 관리하는  (  EntityManager ) 가 필요하다.
  5. JPA를 통한 모든 데이터 변경은 (  트랜잭션  ) 안에서 실행되므로 어노테이션 ( @Transactional )이 필요하다
  6.  ( 스프링 데이터 JPA )는 반복되는 SQL의 CRUD 기능을 모두 제공하여 개발 효율성을 높일 수 있다.
  7. 스프링 데이터 JPA에서 제공하지 않는 함수의 경우 ( 특정한 규칙 )을 따르기만 하면 쿼리문을 자동으로 만들어 함수를 생성해준다.

 

8. JPA 회원 리포지토리에서 모든 멤버를 찾는 쿼리문을 포함하여 findAll 함수를 완성하시오

// MemberRepository.java

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() {
          // 코드 작성
     }

}

 

9. 스프링 데이터 JPA를 사용하도록 하는 코드를 완성하시오.

// SpringConfig.java

// 어노테이션을 작성해주세요.
public class SpringConfig {
     private final MemberRepository memberRepository;
     
     public SpringConfig(MemberRepository memberRepository) {
     	this.memberRepository = memberRepository;
     }
     
     @Bean
     public MemberService memberService() {
     	// 코드 작성
     }
}

 

 

정답

8.

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

 

 

9.

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

 

 

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

 

 

ⓒ 다라

728x90

관련글 더보기