유정잉

스프링부트 JPA [ 다양한 쿼리 생성 방법 ] 본문

네이버 클라우드 부트캠프/복습 정리

스프링부트 JPA [ 다양한 쿼리 생성 방법 ]

유정♡ 2024. 6. 20. 11:12

1. JPARepository에서 제공되는 메서드를 사용하는 방법

2. 메서드 이름으로 쿼리를 생성하는 방법

3. 사용자 정의 쿼리 JPQL(Java Persistence Query Language)

     3-1 Entity기준으로 만드냐 or 3-2 Table기준으로 만드냐

4. 동적 쿼리 처리를 위한 Querydsl - API를 사용(쿼리문이 아니라)

 


 

[ JPARepository에서 제공되는 메서드를 사용하는 방법 ]

public interface CustomerRepository extends JpaRepository<Customer, Long> {

    //1. jparepository에서 제공되는 메서드를 사용하는 방법
    public List<Customer> findByAge(int age); //30

}
public class CustomerController {

    @Autowired
    private CustomerRepository customerRepository;

    @GetMapping("/customer/{age}")
    public ResponseEntity<?> getByAge(@PathVariable int age){
        List<Customer> cus=customerRepository.findByAge(age);
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }

 

 

[ 메서드 이름으로 쿼리를 생성하는 방법 ]

public interface CustomerRepository extends JpaRepository<Customer, Long> {

    //2. 메서드 이름으로 쿼리 생성하는 방법
    public Customer findByUsernameAndPassword(String username, String password); //username과 password가 일치하는 사람
    public Customer findByUsernameIs(String username); //name같은 사람 찾는 메서드
    public List<Customer> findByAgeGreaterThanEqual(int age);

}
@RestController
@RequestMapping("/api")
public class CustomerController {

    @Autowired
    private CustomerRepository customerRepository;

    @PostMapping("/customer")
    public ResponseEntity<?> getUsernameAndPassword(@RequestBody Customer customer) {//<?>반환값의 클래스명이 정해져있지 않다는 뜻
        Customer cus = customerRepository.findByUsernameAndPassword(customer.getUsername(), customer.getPassword());
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }

    @GetMapping("/customer/user/{username}")
    public ResponseEntity<?> getByUsername(@PathVariable String username){
        Customer cus = customerRepository.findByUsernameIs(username);
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }

    @GetMapping("/customer/{age}")
    public ResponseEntity<?> findByAgeGreaterThanEqual(@PathVariable int age){
        List<Customer> cus = customerRepository.findByAgeGreaterThanEqual(age);
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }

}

 

 

[ 사용자 정의 쿼리 JPQL(Java Persistence Query Language) - Entity기준으로 만드냐 or Table기준으로 만드냐 ]

    - 쿼리스트링 쓸 때 ?1 ?2 첫번째값은 1 붙여주고 두번째값은 2 붙여줘서 사용해야함 

    - Table 기준으로 만드는 사용자 정의 쿼리는 : Value과 nativeQuery(기본값 false) 사용

public interface CustomerRepository extends JpaRepository<Customer, Long> {

    //3. 사용자 정의 쿼리 -> JPQL(Java Persistence Query Language) - Entity기준으로 만드냐 
    @Query("select cust from Customer cust where cust.grade=:grade")
    public List<Customer> getGrade(@Param("grade") String grade);
    
    //3. 사용자 정의 쿼리 -> JPQL(Java Persistence Query Language) - Table기준으로 만드냐
    @Query(value = "select * from customer where grade=?1 and name?2", nativeQuery = true)
    public List<Customer> getGrade(@Param("grade") String grade);
    
    @Query(value = "select * from customer cust where cust.username=?1 and cust.password=?2", nativeQuery = true)
    public Customer getUsernameAndPassword(String username, String password);

}
@RestController
@RequestMapping("/api")
public class CustomerController {

    @Autowired
    private CustomerRepository customerRepository;

    @GetMapping("/customer/{grade}")
    public ResponseEntity<?> getGrade(@PathVariable String grade){
        List<Customer> cus = customerRepository.getGrade(grade);
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }

}

 

 

 

[ 동적 쿼리 처리를 위한 Querydsl - API를 사용 ]

   - 환경설정 : build.gradle에 의존성 추가 , config 패키지 생성 후 @Configuration과 @RequiredArgsConstructor 지정, @Bean

   - CustomerDSLRepository에 @Repository와 @RequiredArgsConstructor지정 후 쿼리 작성 

	implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
	annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
	annotationProcessor "jakarta.annotation:jakarta.annotation-api"
	annotationProcessor "jakarta.persistence:jakarta.persistence-api"
package com.example.jpa.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class QueryDSLConfig {

    private final EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }
}

 

  - build -> generated -> sources -> annotationProcessor -> QCustomer 생성 -> 자동으로 쿼리 DSL문 생성됨 그걸 이용 

build -> generated -> sources -> annotationProcessor -> QCustomer 생성 됨

package com.example.jpa.repository;

import com.example.jpa.entity.Customer;
import com.example.jpa.entity.QCustomer;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

@Repository
@RequiredArgsConstructor
public class CustomerDSLRepository {

    private final JPAQueryFactory queryFactory;
    private final JPAQueryFactory jpaQueryFactory;

    public Customer getUsernameAndPassword(String username, String password) {
        QCustomer customer = QCustomer.customer;
        System.out.println("execute");
        
        return jpaQueryFactory.selectFrom(customer)
                .where(customer.username.eq(username)
                        .and(customer.password.eq(password)))
                .fetchOne();
    }
    
        public List<Customer> getGrade(String grade) {
        QCustomer customer = QCustomer.customer;
        return jpaQueryFactory.selectFrom(customer)
                .where(customer.grade.eq(grade))
                .fetch(); 
        }
}
@RestController
@RequestMapping("/api")
public class CustomerController {

    @Autowired
    CustomerDSLRepository customerDSLRepository;

    @PostMapping("/customer")
    public ResponseEntity<?> getUsernameAndPassword(@RequestBody Customer customer) {//<?>반환값의 클래스명이 정해져있지 않다는 뜻
        Customer cus = customerRepository.findByUsernameAndPassword(customer.getUsername(), customer.getPassword());
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }
    
    @GetMapping("/customer/{grade}")
    public ResponseEntity<?> getGrade(@PathVariable String grade){
        List<Customer> cus = customerDSLRepository.getGrade(grade);
        return new ResponseEntity<>(cus, HttpStatus.OK);
    }
}

 

 

728x90