[Spring] JPA

이준영·2022년 9월 30일
0

스프링-입문

목록 보기
13/15

JPA에 대해 알아보자

JDBC에서는 JDBC Template을 쓰더라도 코드를 간소화 시킬수는 있었지만 SQL문을 써야 했다.
JPA는 SQL문 자체를 안쓰게 해준다!!!
이런걸 ORM(Object Relational Mapping)이라고 하는데 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해주는 것을 말한다

  • JPA는 기존의 반복 코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다.
  • JPA를 사용하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환을 할 수 있다.
  • JPA를 사용하면 개발 생산성을 크게 높일 수 있다.

설정

jdbc를 추가할 때와 거의 비슷한데 추가디는 것들이있다

  • 라이브러리 추가
  • JPA 설정 추가
  • New! JPA Entity 매핑
  • JPA 리포지토리 작성
  • New!서비스 계층에 Transaction 추가
  • 스프링 설정 변경

1. JPA, h2DB관련 라이브러리 추가 : build.gradle

 dependencies {
    
	//implementation 'org.springframework.boot:spring-boot-starter-jdbc' 
      implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.h2database:h2'     }
}

2. 스프링 부트에 JPA 설정 추가 : resource/application.properties

spring.jpa.show-sql=true
  spring.jpa.hibernate.ddl-auto=none

3. JPA Entity Mapping : Member(domain)

JPA를 쓰려면 Entity를 매핑해야한다. 방법은 매우매우매우 간단한데 전에 생성한 멤버 클래스에가서 @Entity 붙여주면 된다

@Entity
    public class Member {
    
    	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        
        public Long getId() {
        
        }
        
        ...
        
    }

id 변수 위에 @Id@GeneratedValue(strategy = GenerationType.IDENTITY)를 붙여주었는데
@Id 는 얘를 pk로 쓰겠다는 것이고
@GeneratedValue(..IDENTITY)는 DB가 PK값을 자동으로 생성해주는 것이다.
DB가 알아서 PK를 생성해주는 것을 IDENTITY 라고 한다.

4. JPA 회원 리포지토리

DB 관련 리포지토리 역시 이해하기 어렵지만 jdbc와 비교했을 때 말도 안되게 간단해졌다
여기서 중요한 것은 Entity Maneger

JPA를 쓰려면 EntityManager를 주입받아야 한다.

위에서 설정한 것들로 스프링이 자동으로 EntityManger 클래스를 생성해주는데 리포지토리에서는 스프링이 생성해준 이 EntityManger를 받아서 쓰기만 하면 된다

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 List<Member> findAll() {
          return em.createQuery("select m from Member m", Member.class)
                  .getResultList();
      }
      
      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();
  	  } 
}
 

5. 서비스 계층에 Transaction 추가 : MemberService

JPA를 쓰려면 항상 트랜잭션이 있어야 한다.
@Transaction을 하면 import 할 수 있는게 두개 생기는데 그 중에 org.springframework.transaction.annotation.Transactional 를 사용하자.

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

추가하는 방법은 매우매우매우 간단하다. @Transcation annotaion만 추가해주면 된다

import org.springframework.transaction.annotation.Transactional
...	
    
@Transactional
public class MemberService {
    
...
    
}

6. JPA 사용하도록 스프링 설정 변경

이번에는 해줄게 쪼오오끔 생겼다.

import javax.persistence.EntityManager;
import javax.sql.DataSource;

@Configuration
public class SpringConfig {
	
    private final DataSource dataSource;
	private final EntityManager em;
	
    public SpringConfig(DataSource dataSource, EntityManager em) {
		this.dataSource = dataSource;
		this.em = em;
        
    ...
    
     @Bean
     public MemberRepository memberRepository() {
          //return new MemoryMemberRepository();
          //return new JdbcMemberRepository(dataSource);
          //return new JdbcTemplateMemberRepository(dataSource);
          return new JpaMemberRepository(em);
      }
}

EntityManager를 받아서 생성자를 만들어주는 일이 추가 됐는데 이거 말고는 없다.

profile
화이팅!

0개의 댓글