SpringData 및 JpaRepository

김재현·2023년 12월 18일
0

TIL

목록 보기
62/88

SpringData 및 JpaRepository

열심히 JPA를 공부하고 SpringData 및 JpaRepository 내용을 정리해본다.

SpringData

Spring Data는 Spring 프레임워크에서 데이터 액세스 계층을 간편하게 개발할 수 있도록 도와주는 프로젝트이다. 다양한 데이터베이스 및 데이터 저장소와 통합되어 데이터 액세스 코드를 표준화하고 단순화하는 목적으로 만들어진 덕분에, 개발자는 일관된 방식으로 다양한 데이터 소스에 액세스 할 수 있다. 아주 고맙다!

SpringData 구조

감상: 다양하다.

SpringData 기능 목록

• 강력한 리포지토리 및 사용자 지정 객체 매핑 추상화 --> ORM을 말하는 것
• 리포지토리 메서드 이름에서 동적 쿼리 파생 --> 메서드명만 작성하면 여러 쿼리가 날아가는것
• 기본 속성을 제공하는 구현 도메인 기본 클래스 --> @Entity 등 사용해서 기본 속성 부여 가능
• 명료한 추적기능 지원(생성일시, 마지막 변경일시, 생성자, 마지막 변경자) --> Auditing 기능
• 사용자 지정 리포지토리 코드 통합 가능성
• JavaConfig 및 사용자 지정 XML 네임스페이스를 통한 간편한 Spring 통합 --> 쓸 일 x
• Spring MVC 컨트롤러와의 고급 통합 --> 해이시옷? 하이퍼링크?
• 교차 스토어 지속성에 대한 실험적 지원 --> 사용x

SpringData Jpa 와 JpaRepository 원리

Repository 를 JpaRepository 로 간단하게 바꾸기!

// 변경 전
@Repository
public class UserRepository {

  @PersistenceContext
  EntityManager entityManager;

  public User insertUser(User user) {
    entityManager.persist(user);
    return user;
  }

  public User selectUser(Long id) {
    return entityManager.find(User.class, id);
  }
}
// 변경 후
public interface UserRepository extends JpaRepository<User, Long> {
  
}

[Repository 꿀팁] 기능 제한하기

JpaRepository 는 기본적으로 모든 기능을 제공하기 때문에 리스크가 있을 수 있다.
따라서, 아래와 같은 방법으로 원하는 기능 메소드만 구현하도록 제한할 수 있다.

1. @RepositoryDefinition 을 인터페이스에 붙이는법

가장 많이 쓰이는 방법으로, 이 어노테이션을 붙이면 BeanDefinition 에 직접 접근하여 프로그래밍으로 주입받을 구현체 메소드들을 지정해서 요청할 수 있다.

@RepositoryDefinition(domainClass = Comment.class, idClass = Long.class)
public interface CommentRepository {
    Comment save(Comment comment);
    List<Comment> findAll();
}

2. @NoRepositoryBean 인터페이스로 한번더 감싸는법

상위 인터페이스 개념을 하나 더 만들어서 열어줄 메소드만 선언해준다.

@NoRepositoryBean
public interface MyRepository<T, ID extends Serializable> extends Repository<T, ID> {
    <E extends T> E save(E entity);
    List<T> findAll();
}

[Repository 꿀팁] 기능 추가하기

delete() 메서드를 예시로 들어보자.

delete() 내부 기능

delete() 메소드의 내부 기능의 경우 delete 호출시 영속성 상태인지 확인한다.
영속상태면 그대로 remove, 비영속 상태면 find해오고, 준영속(detached) 상태면 merge해서 다시 조회해온다.
이렇게 하는 이유는 casecade, orphanremoval 도 사용하기 위함이다. 하지만 그 때문에 delete의 성능이 그렇게 좋진 않다.

쿼리가 바로 날아가도록 기능을 개선

만약 casecade, orphanremoval 가 작동 할 필요가 없다면 오버라이딩(커스터마이징)해서 사용 할 수 있다.

@Repository
@Transactional
public class MyRepositoryImpl implements MyRepository {

	@Autowired
	EntityManager entityManager;

	@Override
	public void delete(User user) {
		entityManager.remove(user);
  }
}

simpleJPA의 remove가 아닌 remove를 있는 그대로 호출한것아라 확인과정 없이 바로 삭제 쿼리가 날아간다.

이렇게 delete를 만들어줬을 때, 아래와같이 선택해서 사용하도록 뜬다.

profile
I live in Seoul, Korea, Handsome

0개의 댓글