springframework/Spring Data JPA

Spring Data JPA 의 원리와 소개

Jungsoomin :) 2020. 11. 14. 00:47

지금까지는 JPA 에 대한 설명.

 

학습한 EntityManager 를 이용해서 @Repository 클래스를 만들어 실행 할 수 있으며 형태는 이러하다.

@Repository
public class OldPostRepository {

    @PersistenceContext
    EntityManager entityManager;

    @Transactional
    public Post add(Post post){
        entityManager.persist(post);
        return post;
    }

    @Transactional
    public void delete(Post post){
        entityManager.remove(post);
    }

    @Transactional
    public List<Post> findAll(){
        return entityManager.createQuery("select p from Post as p", Post.class).getResultList();
    }
}
Hibernate: 
    select
        post0_.id as id1_2_,
        post0_.title as title2_2_ 
    from
        post post0_
Post{id=18, title='Spring Data JPA 언제 보나.'}

  • 하지만 진보된 형태를 갖춰나감으로서 JpaRepository <Entity, Id > 인터페이스를 상속하게 되면 interface 만으로도 Repository 를 구현해 낼 수 있게 된다.
  • @Repository 에노테이션 없이도 Spring Bean으로 등록된다.

import me.soomin.datajpa.domain.Post;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PostRepository extends JpaRepository<Post,Long> {

}

JpaRepository<Entity, Id> 인터페이스를 상속하는 인터페이스기본적인 CRUD 메서드를 제공한다.

  • findAll() : Sorting, Pagging
  • findById() : 엔티티 식별자로 값들을 가져 옴
  • delete() : 해당 엔티티 제거
  • deleteAll() 
  • deleteById()
  • save()
  • saveAll()

스프링의 경우 @Configuration 클래스에 @EnableJpaRepositories 가 필요하다. 

  • @EnableJpaRepositories 에서 @Import 하고 있는 JpaRepositoriesRegistrar 가 JPA 리포지토리들을 Spring Bean 으로 등록해준다.
  • 최상위 인터페이스는 ImportBeanDefinitionRegistrar 이며 프로그래밍으로 Bean 을 등록할 수 있게 해준다.

ImportBeanDefinitionRegistrar 를 상속하여 빈을 등록해보자.

 

해당 클래스는 Bean 으로 등록되어 있지 않다.

public class Soomin {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

ImportBeanDefinitionRegistrar 상속 클래스를 만들어 GenericBeanDefinition 클래스로 빈을 만들어 등록한다.

public class SoominRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(Soomin.class);
        beanDefinition.getPropertyValues().add("name", "soominJung");

        registry.registerBeanDefinition("soomin",beanDefinition);
    }
}

스프링 부트는 자동 설정기능을 제공하기에 @EnableJpaRepositories 는 불필요하다.

유심히 봐야할 부분은 설정클래스(@SpringBootApplication) 에서 ImportBeanDefinitionRegistrar 상속 클래스를 @Import 하고 있다는 것이다.

@SpringBootApplication
@EnableJpaRepositories
@Import(SoominRegistrar.class)
public class DatajpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(DatajpaApplication.class, args);
    }

}

그렇게 되면 프로그래밍을 절차를 거쳐 Spring Bean을 등록하여 사용할 수 있게 되며 이보다 더욱 더 복잡한 내부과정을 가지고 있는 것이 JpaRepositoriesResgistrar 이다.

@Component
@Transactional
public class JpaParentChileRunner implements ApplicationRunner {

    @Autowired
    private PostRepository postRepository;

    @Autowired
    private Soomin soomin;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(soomin.getName());
//        postRepository.findAll().forEach(System.out::println);
    }
}

'springframework > Spring Data JPA' 카테고리의 다른 글

Spring Data JPA 활용 개요.  (0) 2020.11.15
JPA 생성 쿼리 파라미터 로깅, Spring Data JPA 사용시 명심해야 할 것들  (0) 2020.11.14
Query  (0) 2020.11.13
Fetch 전략  (0) 2020.11.13
Cascade, Entity 상태  (0) 2020.11.13