안녕하세요. J4J입니다.
이번 포스팅은 JPA 조건절(where) 메서드에 대해 적어보는 시간을 가져보려고 합니다.
들어가기에 앞서 이전에 작성된 포스팅을 읽고 오시면 더 이해가 잘 되실 겁니다.
2021.03.21 - [Spring/JPA] - [JPA] JPA 환경설정
2021.03.22 - [Spring/JPA] - [JPA] JPA Repository설정 및 CRUD
조건절(where) 메서드
앞서 포스팅에서 "JPA는 쿼리를 따로 작성하지 않고 인터페이스 구현만으로 실제 쿼리가 작성된 것처럼 동작하도록 해준다"라고 말한 적이 있습니다.
그렇기 때문에 만약 쿼리에 작성되던 조건절을 사용하고 싶다면 단순하게 JpaRepository 인터페이스에 메서드만 작성해주면 됩니다.
이전 포스팅에서 사용했던 SchoolRepository를 기반으로 데이터를 조회하는데 사용될 수 있는 메서드를 작성하면 다음과 같은 것들이 있습니다.
package com.spring.jpa.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.spring.jpa.dto.School;
public interface SchoolRepository extends JpaRepository<School, Integer> { // 제네릭 타입: <엔티티 클래스, 엔티티클래스의 기본키>
// 단순 조건
public School findByName(String name); // where name = ?
public List<School> findByRegion(String region); // where region = ?
// not
public List<School> findByRegionNot(String region); // where region <> ?
// and
public List<School> findByNameAndRanking(String name, int ranking); // where name = ? and ranking = ?
// or
public List<School> findByNameOrRanking(String name, int ranking); // where name = ? or ranking = ?
// between
public List<School> findByRankingBetween(int startRanking, int endRanking); // where ranking between ? and ?
// 부등호
public List<School> findByRankingLessThan(int ranking); // where ranking < ?
public List<School> findByRankingLessThanEqual(int ranking); // where ranking <= ?
public List<School> findByRankingGreaterThan(int ranking); // where ranking > ?
// null
public List<School> findByRankingIsNull(); // where ranking is null
public List<School> findByRankingIsNotNull(); // where ranking is not null
// like
public List<School> findByNameStartingWith(String name); // where name like ?%
public List<School> findByNameEndingWith(String name); // where name like %?
public List<School> findByNameContaining(String name); // where name like %?%
// in
public List<School> findByIdIn(List<Integer> id); // where school_id in (?, ?, ? ...)
public List<School> findByIdNotIn(List<Integer> id); // where school_id not in (?, ?, ? ...)
// order by
public List<School> findAllByOrderById(); // order by school_id, "AllBy" 주의
public List<School> findByNameContainingOrderByRanking(String name); // where name like %?% order by ranking
public List<School> findByIdOrderByIdDesc(int id); // where id = ? order by id desc
}
기본적인 사용방법은 위와 같고 조건이 많이 붙을 경우에는 원하는 조건절을 추가적으로 이어서 작성해주시면 됩니다.
예를 들어 ranking이 2와 3사이고 그중 name에 "경기"라는 값이 들어있는 데이터를 조회하고 싶다면 다음과 같이 메서드를 작성하시면 됩니다.
public List<School> findByRankingBetweenAndNameContaining(int startRanking, int endRanking, String name); // where ranking between ? and ? and name like %?%
작성된 메서드가 올바르게 동작되는지 단위 테스트를 이용하여 확인해보겠습니다.
package com.spring.jpa;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import com.spring.jpa.config.RootContext;
import com.spring.jpa.repository.SchoolRepository;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = RootContext.class)
@Slf4j
public class JPATest {
@Autowired
SchoolRepository schoolRepository;
@Test
public void Test() {
log.info(schoolRepository.findByRankingBetweenAndNameContaining(2, 3, "경기").toString());
}
}
코드를 작성하면 위와 같이 나오게 될 것이고 실행하게 되면 다음과 같은 결과가 출력됩니다.
INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4d41cee, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@3712b94, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2833cc44, org.springframework.test.context.support.DirtiesContextTestExecutionListener@33f88ab, org.springframework.test.context.transaction.TransactionalTestExecutionListener@27a8c74e, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@2d8f65a4, org.springframework.test.context.event.EventPublishingTestExecutionListener@1b68ddbd]
INFO : org.springframework.data.repository.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
INFO : org.springframework.data.repository.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 137ms. Found 1 JPA repository interfaces.
INFO : org.hibernate.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: jpa-mysql]
INFO : org.hibernate.Version - HHH000412: Hibernate Core {5.4.10.Final}
INFO : org.hibernate.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
INFO : org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
INFO : org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
INFO : org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'jpa-mysql'
Hibernate:
/* select
generatedAlias0
from
School as generatedAlias0
where
(
generatedAlias0.ranking between :param0 and :param1
)
and (
generatedAlias0.name like :param2 escape :param3
) */ select
school0_.school_id as school_i1_0_,
school0_.name as name2_0_,
school0_.ranking as ranking3_0_,
school0_.region as region4_0_
from
school school0_
where
(
school0_.ranking between ? and ?
)
and (
school0_.name like ? escape ?
)
INFO : com.spring.jpa.JPATest - [School(id=4, name=경기 고등학교, region=경기, ranking=2)]
INFO : org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'jpa-mysql'
추가적으로 조회 뿐만 아니라 삭제를 위한 조건절에서도 deleteBy~와 같은 모습으로 메서드를 생성하여 사용하시면 됩니다.
참고
이상으로 JPA 조건절(where) 메서드에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Spring > JPA' 카테고리의 다른 글
[JPA] 연관관계 매핑 (단방향) (0) | 2021.03.26 |
---|---|
[JPA] 복합키(Composite Key) 엔티티 (2) | 2021.03.24 |
[JPA] JPA Repository설정 및 CRUD (0) | 2021.03.22 |
[JPA] JPA 환경설정 (0) | 2021.03.21 |
[JPA] Composite-id class must implement Serializable 에러 (0) | 2021.03.17 |
댓글