diff --git a/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberRepository.java b/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberRepository.java index a66b3a7d..c3bf0463 100644 --- a/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberRepository.java +++ b/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberRepository.java @@ -14,7 +14,7 @@ import java.util.Collection; import java.util.List; import java.util.Optional; -public interface MemberRepository extends JpaRepository, MemberRepositoryCustom{ +public interface MemberRepository extends JpaRepository, MemberRepositoryCustom, JpaSpecificationExecutor{ List findByUsernameAndAgeGreaterThan(String username, int age); diff --git a/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberSpec.java b/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberSpec.java new file mode 100644 index 00000000..e405f73f --- /dev/null +++ b/spring-data-jpa/src/main/java/com/example/springdatajpa/repository/MemberSpec.java @@ -0,0 +1,33 @@ +package com.example.springdatajpa.repository; + +import com.example.springdatajpa.entity.Member; +import com.example.springdatajpa.entity.Team; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.ObjectUtils; + +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; + +public class MemberSpec { + + public static Specification teamName(final String teamName) { + return (root, query, criteriaBuilder) -> { + + if (ObjectUtils.isEmpty(teamName)) { + return null; + } + + Join t = root.join("team", JoinType.INNER);// 회원과 조인 + return criteriaBuilder.equal(t.get("name"), teamName); + }; + } + + public static Specification username(final String username) { + return (root, query, criteriaBuilder) -> { + if (ObjectUtils.isEmpty(username)) { + return null; + } + return criteriaBuilder.equal(root.get("name"), username); + }; + } +} diff --git a/spring-data-jpa/src/test/java/com/example/springdatajpa/repository/MemberRepositoryTest.java b/spring-data-jpa/src/test/java/com/example/springdatajpa/repository/MemberRepositoryTest.java index 80511076..43197ca9 100644 --- a/spring-data-jpa/src/test/java/com/example/springdatajpa/repository/MemberRepositoryTest.java +++ b/spring-data-jpa/src/test/java/com/example/springdatajpa/repository/MemberRepositoryTest.java @@ -11,6 +11,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; import org.springframework.test.annotation.Rollback; import org.springframework.transaction.annotation.Transactional; @@ -310,7 +311,27 @@ public class MemberRepositoryTest { @Test void callCustom() { List result = memberRepository.findMemberCustom(); + } + @Test + void specBasic() { + // given + Team teamA = new Team("teamA"); + em.persist(teamA); + + Member member1 = new Member("member1", 0, teamA); + Member member2 = new Member("member2", 0, teamA); + em.persist(member1); + em.persist(member2); + + em.flush(); + em.clear(); + + // when + Specification spec = MemberSpec.username("member1").and(MemberSpec.teamName("teamA")); + List result = memberRepository.findAll(spec); + + assertEquals(1, result.size()); } }