[spring] JPA (스프링 입문 by 김영한)

su_y2on·2022년 1월 13일
0

Spring

목록 보기
11/30
post-thumbnail

JPA

드디어 JPA입니다~ JdbcTemplate도 Jdbc에 비하면 코드작성이 편리해졌지만... 여전히 SQL문 작성, mapper 등에서 불편함을 가지고 있습니다.

JPA를 이용해보면서 얼마나 편한지 직접 느껴보도록하겠습니다..😆


세팅

먼저 build.gradle에 아래 두개 라이브러리 추가, jdbc관련 라이브러리는 Jpa가 포함하고 있으니 삭제

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'

그리고 resources/application.properties에 정보를 추가해줍니다
각 정보에 대한 주석설명은 참고만 해주시고 코드작성 시 빼고 작성해주세요!

spring.jpa.show-sql=true // jpa가 생성하는 sql출력
  spring.jpa.hibernate.ddl-auto=none // 자동으로 table생성 막기 



매핑

JPA는 ORM이기 때문에 DB와 매핑을 해주어야합니다 따라서 아래와 같이
예전에 정의해놨던 Member class로 가서 entity로 매핑해보겠습니다.
@Id는 pk값으로 정하겠다는 뜻이고 또 GenerationType.IDENTITY는 pk 자동생성입니다.

@Entity
public class Member {

        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        
        ...
}



Repository

이제 새로 레포지토리를 작성하면 다음과 같습니다.

public class JpaMemberRepository implements MemberRepository {

      private final EntityManager em;
      
      public JpaMemberRepository(EntityManager em) {
          this.em = em;
	}
	....
    
}

나머지 코드들은 다음과 같습니다. jdbc와 비교하면 정말 간단해졌습니다🥲✨✨

	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();
}

여기서 하나 주의할 것은 마지막 findByName에서 createQuery부분에 들어간 문자열이 sql이 아닌 jpql이라는 쿼리언어라는 것입니다. from절에서 객체 자체를 참조하기 때문에 select문에서도 m은 Member객체 자체입니다. 따라서 sql처럼 mapper를 사용해줄 필요가 없이 Member 데이터를 반환해줍니다


Transactional

마지막으로 JPA를 사용할 때 데이터를 저장하거나 변경하려면 @Transactional을 붙여줘야합니다!
따라서 memberService에서 join(데이터 생성)을 쓰고있기 때문에 가서 붙여주도록 하겠습니다 :)

@Transactional
  public class MemberService {}



SpringConfig

마지막으로 레포지토리를 빈으로 등록해주도록 하겠습니다. 그리고 아까부터 계속보이는 entityManger에 대해 설명하자면 JPA는 entityManger로 모든 일들을 수행하게됩니다. 이는 jpa 라이브러리가 있다면 스프링이 생성해주고 따라서 생성자로 DI받을 수 있습니다.

@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 JdbcTemplateMemberRepository(dataSource);
            return new JpaMemberRepository(em);
        }          
            
       
}

0개의 댓글