728x90
스프링 데이터 JPA
2. 핵심 개념 이해
본격적인 스프링 데이터 JPA 활용법을 학습하기에 앞서, ORM과 JPA에 대한 이론적인 배경을 학습합니다
포스팅 참조 정보
GitHub
공부한 내용은 GitHub에 공부용 Organizations에 정리 하고 있습니다
해당 포스팅에 대한 내용의 GitHub 주소
실습 내용이나 자세한 소스코드는 GitHub에 있습니다
포스팅 내용은 간략하게 추린 핵심 내용만 포스팅되어 있습니다
https://github.com/freespringlecture/spring-data-jpa-study/tree/chap02-05-jpa_principle
해당 포스팅 참고 인프런 강의
실습 환경
- Java Version: Java 11
- SpringBoot Version: 2.1.2.RELEASE
5. 스프링 데이터 JPA 소개 및 원리
JpaRepository<Entity, Id>
인터페이스
- 매직 인터페이스
@Repository
가 없어도 빈으로 등록해 줌
@EnableJpaRepositories
매직의 시작은 여기서 부터
매직은 어떻게 이뤄지나?
JpaRepository
로 구현한 Repository가 어떻게 자동으로 빈으로 등록됐는지는 아래의 클래스에서 확인
- 시작은
@Import(JpaRepositoriesRegistrar.class)
- 핵심은
ImportBeanDefinitionRegistrar
인터페이스- SpringFrameWork의 인터페이스이며 구현체가 다양함
- 빈을 프로그래밍을 통해서 등록할 수 있게 해줌
JpaRepository
를 상속받은 모든 인터페이스들을 찾아서 빈으로 등록해줌
ImportBeanDefinitionRegistrar
예제
Freelife를 빈으로 등록하는 예제
Freelife 클래스 구현
public class Freelife {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
FreelifeRegistrar 클래스 구현
빈으로 등록하는 프로그래밍 과정
public class FreelifeRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(Freelife.class);
beanDefinition.getPropertyValues().add("name", "Superman");
registry.registerBeanDefinition("freelife", beanDefinition);
}
}
@Import
설정
최종적으로 아래와 같이 설정하면 프로그래밍에 의해서 자동으로 빈으로 등록됨
@SpringBootApplication
@Import(FreelifeRegistrar.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
등록된 빈을 주입받아서 출력 테스트
@Component
@Transactional
public class JpaRunner implements ApplicationRunner {
@Autowired
Freelife freelife;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("=====================");
System.out.println(freelife.getName());
}
}
예전 방식
코드도 작성하고 테스트도 해야되고 매우 번거로움
@Repository
@Transactional
public class PostRepository {
@PersistenceContext
EntityManager entityManager;
public Post add(Post post) {
entityManager.persist(post);
return post;
}
public void delete(Post post) {
entityManager.remove(post);
}
public List<Post> findAll() {
return entityManager.createQuery("SELECT p FROM Post AS p", Post.class)
.getResultList();
}
}
예전 정의 방식
예전에는 기본적인 코드들은 만들어서 정의해서 사용하는 프레임워크가 유행했었음
@Repository
public class PostRepository extends GenericRepository<Post, Long> {
}
현재의 방식
- PostRepository 라는 interface를 만들고
JpaRepository
라는 interface를 상속받음 JpaRepository
첫번째 타입은 Entity 타입이고 두번째 타입은 Entity에서 사용하는 PK의 Type@EnableJpaRepositories
는 스프링부트가 자동 설정해줌- 아래와 같이 구현하면
@Repository
를 지정할 필요없이 빈으로 등록됨
PostRepository 인터페이스 구현
public interface PostRepository extends JpaRepository<Post, Long> {
}
JpaRunner 테스트 구현
EntityManager로 복잡하게 구현했던 Code를 SpringDataJPA를 통해 안정적으로 검증된 Code를 사용하여 간결하게 구현가능
생산성, 유지보수성, 코드의 간결함, 간결한 코드로 인해 테스트 작성이 불필요함
@Component
@Transactional
public class JpaRunner implements ApplicationRunner {
@Autowired
PostRepository postRepository;
@Override
public void run(ApplicationArguments args) throws Exception {
postRepository.findAll().forEach(System.out::println);
}
}
728x90
'개발강의정리 > Spring' 카테고리의 다른 글
[스프링 부트 개념과 활용] 4-10. 스프링 데이터 8부: 데이터베이스 마이그레이션 (0) | 2019.11.23 |
---|---|
[스프링 데이터 JPA] 2-6. 핵심 개념 이해 정리 (0) | 2019.11.22 |
[스프링 데이터 JPA] 2-4. JPA 프로그래밍 7: Query (0) | 2019.11.22 |
[스프링 데이터 JPA] 2-4. JPA 프로그래밍 6: Fetch (0) | 2019.11.22 |
[스프링 데이터 JPA] 2-4. JPA 프로그래밍 5: Entity 상태와 Cascade (0) | 2019.11.22 |
댓글