스프링부트 쇼핑몰 프로젝트(2)

Study with cocochichi·2023년 11월 22일
post-thumbnail

🛒 쿼리 메소드

: 쿼리 메소드는 스프링 데이터 JPA에서 제공하는 핵심 기능 중 하나로 Repository 인터페이스에 간단한 네이밍 룰을 이용하여 메소드 작성하면 원하는 쿼리 실행 가능

find + (엔티티 이름) + By + 변수이름

🛒 쿼리 메소드를 이용한 상품 조회하기

➡️ itemNm(상품명)으로 데이터를 조회하기 위해서 By 뒤에 필드명인 ItemNm을 메소드의 이름에 붙여줌. 엔티티명은 생략 가능하므로 findItemByItemNm 대신 findByItemNm으로 메소드명 만들어줌. 매개변수로는 검색할 때 사용할 상품명 변수를 넘겨줌.

➡️ 1) 테스트 코드 실행 시 데이터베이스에 상품 데이터가 없으므로 테스트 데이터 생성을 위해서 10개의 상품을 저장하는 메소드를 작성하여 findByItemNmTest()에서 실행.

➡️ 2) ItemRepository 인터페이스에 작성했던 findByItemNm 메소드를 호출함. 파라미터는 "테스트 상품1"이라는 상품명을 전달.

➡️ 3) 조회 결과 얻은 item 객체들을 출력

✏️ 쿼리 메소드 Sample 및 JPQL snippet

🛒 OR조건 처리하기

➡️ 상품을 상품명과 상품 상세 설명을 OR조건을 이용해 조회

➡️ 1) 기존에 만들었던 테스트 상품을 만드는 메소드를 실행하여 조회할 대상 만듦.
➡️ 2) 상품명이 "테스트 상품1" 또는 상품 상세 설명이 "테스트 상품 상세 설명5"이면 해당 상품을 itemList에 할당함. 테스트 코드를 실행하면 조건대로 2개의 상품이 출력됨

🛒 LessThan조건 처리하기

➡️ 파라미로 넘어온 price 변수보다 값이 작은 상품 데이터를 조회
➡️ 현재 데이터베이스에 저장된 가격은 10001 ~ 10010. 테스트 코드 실행 시 10개의 상품을 저장하는 로그가 콘솔에 나타나고 맨 마지막에 가격이 10005보다 작은 4개의 상품을 출력함

🛒 OrderBy로 정렬 처리하기

오름차순 : OrderBy + 속성명 + Asc
내림차순 : OrderBy + 속성명 + Desc

🛒 Spirng DATA JPA @Query 어노테이션

SQL : 데이터베이스의 테이블을 대상으로 쿼리 수행
JPQL : 엔티티 객체를 대상으로 쿼리 수행 (객체지향쿼리)

➡️ SQL을 추상화 해서 사용하기 때문에 특정 데이터베이스 SQL에 의존하지 않음. 즉, JPQL로 작성했다면 데이터베이스가 변경되어도 애플리케이션이 영향 받지 않음!

🛒 @Query를 이용한 검색 처리

➡️ 1) @Query 안에 JPQL로 작성한 쿼리문을 넣어줌. from 뒤에는 엔티티 클래스로 작성한 Item을 지정해주고, Item으로부터 데이터를 select 하겠다는 의미
➡️ 2) 파라미터에 @Param 이용하여 파라미터로 넘어온 값을 JPQL에 들어갈 변수로 지정해줌. 현재는 itemDetail 변수를 "like % %" 사이에 ":itemDetail"로 값이 들어가도록 작성

🛒 @Query-nativeQuery 속성 예제

기존의 데이터베이스에서 사용하던 쿼리를 그대로 사용해야 할 때는 @Query의 nativeQuery 속성을 사용하면 기존 쿼리를 그대로 활용 가능함 ➡️ 하지만 종속되는 쿼리문을 사용하기 때문에 독립적이라는 장점을 잃음


🛒 Spring DATA JPA Querydsl

@Query 안에 JPQL 문법으로 문자열을 입력하기 때문에 잘못 입력하면 컴파일 시점에서 에러를 발견할 수 없다!
➡️ 이를 보완하는 방법으로 Querydsl 사용

  • Querydsl 장점

    • 고정된 SQL문이 아닌 조건에 맞게 동적으로 쿼리를 생성 가능
    • 비슷한 쿼리를 재사용할 수 있으며 제약 조건 조립 및 가독성을 향상시킬 수 있음
    • 문자열이 아닌 자바 소스코드로 작성하기 때문에 컴파일 시점에 오류를 발견할 수 있음
    • IDE의 도움을 받아서 자동 완성 기능을 이용할 수 있기 때문에 생산성을 향상시킬 수 있음

업로드중.. ➡️ Querydsl 사용하기 위한 설정
(버전을 주석처리 해줬음! 스프링부트 버전이 달라서 메이븐 컴파일 수행이 안됐기 때문에)

		// <dependencies></dependencies> 사이에 삽입
		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-jpa</artifactId>
			<version>4.3.1</version>
		</dependency>
		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-apt</artifactId>
			<version>4.3.1</version>
		</dependency>

업로드중..➡️ QItem 클래스가 생성됨. Item 클래스의 모든 필드들에 대해서 사용 가능한 peration을 호출 메소드가 정의

// <plugins></plugins> 사이에 삽입
			<plugin>
				<groupId>com.mysema.maven</groupId>
				<artifactId>apt-maven-plugin</artifactId>
				<version>1.1.3</version>
				<executions>
					<execution>
						<goals>
							<goal>process</goal>
						</goals>
						<configuration>
							<outputDirectory>
								target/generated-sources/java
							</outputDirectory>
							<processor>
								com.querydsl.apt.jpa.JPAAnnotationProcessor
							</processor>
						</configuration>
					</execution>
				</executions>
			</plugin>

🛒 JPAQueryFactory를 이용한 상품 조회 예제 업로드중..

➡️ 1) 영속성 컨텍스트를 사용하기 위해 @PersistenceContext 를 이용해 EntityManager 빈을 주입함
➡️ 2) JPAQueryFactory를 이용해 쿼리를 동적으로 생성. 생성자의 파라미터로는 EntityManager 객체를 넣어줌
➡️ 3) Querydsl을 통해 쿼리를 생성하기 위해 플러그인을 통해 자동으로 생성된 QItem 객체를 이용
➡️ 4) 자바 소스코드지만 SQL문과 비슷하게 소스 작성 가능
➡️ 5) JPAQuery 메소드 중 하나인 fetch를 이용해 쿼리 결과를 리스트로 반환. fetch() 메소드 실행 시점에 쿼리문이 실행됨.
업로드중..

✏️ JPAQuery 데이터 반환 메소드

메소드기능
List< T> fetch()조회 결과 리스트 반환
T fetchOne조회 대상이 1건인 경우 제네릭으로 지정한 타입 반환
T fetchFirst()조회 대상 중 1건만 반환
Long fetchCount()조회 대상 개수 반환
QueryResult< T> fetchResults()조회한 리스트와 전체 개수를 포함한 QueryResults 반환

🛒 QueryDslPredicateExecutor를 이용한 상품 조회 예제

Predicate : '이 조건이 맞다'고 판단하는 근거를 함수로 제공하는 것
➡️ Repository에 Predicate를 파라미터로 전달하기 위해서 QueryDslPredicateExecutor 인터페이스를 상속 받음

✏️ QueryDslPredicateExecutor 인터페이스 정의 메소드

메소드기능
long count(Predicate)조건에 맞는 데이터의 총 개수 반환

업로드중..➡️ QueryDslPredicateExecutor 인터페이스 상속을 추가

✏️ QueryDslPredicateExecutor 인터페이스 정의 메소드

메소드기능
long count(Predicate)조건에 맞는 데이터의 총 개수 반환
boolean exists(Predicate)조건에 맞는 데이터 존재 여부 반환
Iterable findAll(Predicate)조건에 맞는 모든 데이터 반환
Page< T> findAll(Predicate, Pageable)조건에 맞는 페이지 데이터 반환
Iterable findAll(Prediacte, Sort)조건에 맞는 정렬된 데이터 반환
T findOne(Predicate)조건에 맞는 데이터 1개 반환

업로드중.. ➡️ 1) 상품 데이터를 만드는 새로운 메소드를 하나 만듦. 1번 ~ 5번 상품의 판매상태를 SELL 지정하고, 6번 ~ 10번 판매상태를 SOLD_OUT 세팅해서 생성

업로드중.. ➡️ 2) BooleanBuilder는 쿼리에 들어갈 조건을 만들어주는 빌더. Predicate를 구현하고 있으며 메소드 체인 형식으로 사용 가능함
➡️ 3) 필요한 상품을 조회하는데 필요한 "and"조건을 추가하고 있음. 상품의 판매상태가 SELL일 때만 booleanBuilder에 판매상태 조건을 동적으로 추가하는 것을 볼 수 있음.
➡️ 4) 데이터를 페이징해 조회하도록 PageRequest.of() 메소드를 이용해 Pagealbe 객체를 생성. 첫번째 인자는 조회할 페이지의 번호, 두번째 인자는 한 페이지당 조회할 데이터의 개수를 넣어줌.
➡️ 5) QueryDslPredicateExecutor 인터페이스에서 정의한 findAll() 메소드를 이용해 조건에 맞는 데이터를 Page 객체로 받아옴
업로드중..

0개의 댓글