본문 바로가기
Spring/JPA

[JPA] 조건절(where) 메서드

by J4J 2021. 3. 23.
300x250
반응형

안녕하세요. 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~와 같은 모습으로 메서드를 생성하여 사용하시면 됩니다.

 

 

참고

 

Spring Data JPA Query 사용 - 1편

 

 

 

 

이상으로 JPA 조건절(where) 메서드에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

728x90
반응형

댓글