Spring에서 사용되는 DB 접근 기술 중 하나
repository에 구현체 없이 인터페이스만으로 개발이 가능하다.
기본적인 CRUD 제공
기본 제공 메소드가 아닐 경우에도 스프링 데이터 JPA가 메소드 이름을 분석해서 JPQL을 실행
주요 메소드
- save() : 새로운 엔티티는 저장하고 이미 있는 경우 update
- delete() : 삭제
- findAll() : 모든 엔티티 조회 (sort, pageable 조건을 파라미터로 제공_)
- findOne() : 엔티티 하나를 조회
@Entity
@NamedQuery(
name = "Member.findByUsername",
query = "select m from Member m where m.username = :username")
public class Member {
}
JPA를 직접 사용해서 Named 쿼리 호출
public class MemberReposiory {
public List<Member> findByUsername(String username) {
List<Member> resultList =
em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", "회원1")
.getResultList();
}
}
스프링 데이터 JPA로 Named 쿼리 호출
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsername(@Param("username") String username);
}
public interface MemberRepository extends JpaRepository<Member, Long> {
// 이름 기반 파라미터 바인딩
@Query("select m from Member m where m.username = :name",
nativeQuery = true)
Member findByUsername(@Param("name") String username);
}
age 이상의 나이를 가진 Member의 나이를 모두 update
public int agePlus(int age) {
return em.createQuery("update Member m set m.age = m.age+1 where m.age >= :age")
.setParameter("age", age)
.executeUpdate();
// executeUpdate를 실행하기 위한 어노테이션
@Modifying(clearAutomatically = true)
@Query("update Member m set m.age = m.age+1 where m.age >= :age")
int agePlus(@Param("age") int age);
- 벌크성 수정 / 삭제 쿼리는 영속성 컨텍스트를 거치지 않고 수행된다
-> 기존에 영속성 컨텍스트에 남아있는 데이터와 불일치를 발생시킬 수 있다- 벌크성 수정 / 삭제 쿼리를 한 후에는 반드시 영속성 컨텍스트를 초기화 시켜야 한다 (혹은 영속성 컨텍스트로 엔티티가 관리되기 전에 수행해도 괜찮다)
- 순수 JPA Repository라면 em.flush() / em.clear()를 해야하지만 스프링 데이터 JPA는 이러한 기능을 옵션으로 제공
--> @Modifying(clearAutomatically = true)