Spring Boot - JPA로 쿼리 제어하기(NativeQuery), Entity Manager 설정, persistence.xml 설정, 프로시저 사용하기

반응형

예제 파일

https://github.com/luvris2/spring-boot-jap-nativequery

 

GitHub - luvris2/spring-boot-jap-nativequery

Contribute to luvris2/spring-boot-jap-nativequery development by creating an account on GitHub.

github.com

 

서론

JPA로 CRUD말고 함수나 프로시저 호출은 어떻게 해야하지?

 

사용 환경

  • IDE : IntelliJ
  • Java : Open JDK 17
  • Project : Grade
  • DB : SSMS (MS-SQL)
  • DB Management : JPA

프로젝트 설정

MS-SQL / JPA 라이브러리 추가

  • build.grade - dependencies
dependencies {
	// MS-SQL
    runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc:9.2.1.jre11'
    // JPA
    implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
}

데이터베이스 연결 설정 (application.yml)

  • application.properties일 경우, Refactor - Rename을 통해 확장자를 yml로 변경
# application.yml
spring:
  datasource:
    url: jdbc:sqlserver:// your host name : port ;databaseName= your DB name
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    username: your name
    password: your password

JPA 설정

persistence.xml

  • JPA를 사용하여 데이터베이스와 상호작용하는데 필요한 설정 파일
  • 데이터베이스 연결 정보, JPA 엔티티 클래스 위치, JPA 프로바이더 정보 등 포함
  • 엔티티 매니저를 생성하는데 사용
  • JPA가 애플리케이션에서 엔티티 매니저를 만들 때 필요한 정보를 제공
  • 경로 : resources - META-INF에 위치

* 엔티티 매니저(Entity Manager) : JPA에서 객체와 데이터베이스 사이의 매핑을 처리하는 주요 클래스

  • 파일 위치
    • META-INF 폴더가 없을 경우에는 직접 디렉토리 생성 후 persistence.xml 파일 추가


  • persistence.xml 설정
    • persistence-unit name : JPA에서 엔티티를 제어 할 수 있는 유닛의 이름을 정의, 즉 해당 유닛으로 쿼리 사용 예정
    • class : 엔티티가 존재하는 클래스, 함수나 프로시저'만' 사용 할 예정이라면 굳이 적어줄 필요 없음
    • property
      • 데이터베이스 드라이버, 데이터소스 url, 사용자명, 비밀번호 입력
      • DB 설정을 또 하는 이유?
        • application.yml : DB에 접속하기 위함
        • persistence.xml : persistence unit이 DB를 제어하기 위함
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                                 http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
    <persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>org.example.config.TestTable</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver:// 'your host name' : 'port number';databaseName= 'your database name' "/>
            <property name="javax.persistence.jdbc.user" value=" your user name "/>
            <property name="javax.persistence.jdbc.password" value=" your password "/>
        </properties>
    </persistence-unit>
</persistence>

Persistence 클래스 생성

Entity Manager Factory 클래스 생성

  • 엔티티 매니저 팩토리를 정의하기 위한 클래스 생성
  • Entity Manager Factory
    • Persistence-unit(지속성 단위)를 구축
    • 데이터베이스와 상호작용하기 위해 하나 이상의 Entity Manager 인스턴스를 생성하는데 사용
// JpaUtils.java

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class JpaUtils {
	// PERSISTENCE_UNIT_NAME : 영속성 단위 이름 정의
    private static final String PERSISTENCE_UNIT_NAME = "myPersistenceUnit";

	// 엔티티 매니저 팩토리 생성
    private static final EntityManagerFactory emFactory;
    static {
        emFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    }

	// 엔티티 매니저 팩토리 객체 반환
    public static EntityManager getEntityManager() {
        return emFactory.createEntityManager();
    }
}

Entity Manager 클래스 생성

  • 쿼리 작업을 진행할 클래스 생성
  • Entity Manager
    • 자바 객체인 엔티티의 수명 주기 관리를 담당
    • 엔티티, 트랜잭션, 쿼리, 캐시, 엔티티의 관계, 동시성 등을 제어
  • createNativeQuery
    • SQL 쿼리를 실행해주는 명령어
    • 파라미터의 값은 콜론(:)으로 파라미터를 정의
    • 쿼리 뒤에 엔티티의 이름을 명시해주면 해당 엔티티의 데이터 타입으로 반환
      • 단, 뒤에 .class를 꼭 붙여야 함
  • .setParameter("파라미터명", 값)
    • createNativeQuery에서 정의한 파라미터의 이름과 값 입력
  • .getResultList
    • 데이터베이스에서 실행한 쿼리 결과를 리스트의 형태로 반환
    • 데이터 타입은 Object이므로 Object의 형태로 받아야 함
    • 혹은 엔티티를 설정할 경우, 해당 엔티티의 리스트로 받으면 캐스팅을 진행 할 필요 없음
// JpaQuery.java

import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import java.util.*;

public class JpaQuery {
    private static List executeNamedQuery(int paramValue) {
        EntityManager em = JpaUtils.getEntityManager();

        // 쿼리 단위 실행
        Query query = em.createNativeQuery("exec test :a");
		// 엔티티의 데이터 타입으로 반환
        // Query query = em.createNativeQuery("exec test :a", Entity.class);

        // 쿼리에 들어갈 파라미터 설정
        query.setParameter("a", 2);

        // 쿼리 결과를 리스트로 반환
        List<Object[]> resultList = query.getResultList();

        // 결과를 저장 할 변수 선언
        List result = new ArrayList<>();

        // 각 행의 열 저장
        for ( Object[] row : resultList ) {
            result.add( (Integer) row[0] );
            result.add( (Integer) row[1] );
        }

        em.close();
        return result;
    }

    public static List doNameQuery(int paramValue) {
        // 쿼리 결과 반환
        return executeNamedQuery(paramValue);
    }

}

쿼리 실행 및 데이터 확인 (SSMS)

  • 위에 기재되어 있는 쿼리는 테스트를 위해 간단하게 작성한 SSMS(MS-SQL)의 프로시저입니다.
  • 숫자가 들어오면 해당 숫자와 제곱된 숫자의 값을 반환하는 프로시저
  • 프로시저 정의 (프로시저명:test)
/* 수를 입력하면 입력한 수와 제곱을 반환하는 프로시저 */
CREATE PROC test
	@a int
AS
BEGIN
	DECLARE @result int
	SET @result = @a * @a
	SELECT @a as "num1", @result as "result"
END

 

  • 프로시저 실행
/* 프로시저 실행 */
exec test 2

 

  • 프로시저 실행 결과


스프링 부트에서 프로시저 실행 결과 확인

  • 값이 정상적으로 넘어오는지 메인 파일에 코드 작성
  • 위에서 작성한 함수 'doNameQuery'를 이용하여 프로시저의 결과 값을 받아보기
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.List;
import static org.example.config.JpaQuery.doNameQuery;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);

		// 프로시저 실행, 파라미터 값 2 입력
        List result = doNameQuery(2);

		// 프로시저 실행 결과
        System.out.println("input value : " + result.get(0));
        System.out.println("result : " + result.get(1));
    }
}

 

  • 실행 결과


이 포스팅은 DB 값을 받고 확인하기 위한 목적으로 작성하였하였습니다.

데이터를 웹 화면에 출력하고 싶다면 아래의 포스팅을 참고해주세요

https://luvris2.tistory.com/412

 

Spring Boot - 웹 페이지에 DB 데이터 조회하기 (컨트롤러, 모델, html)

포스팅 정보 - 해당 포스팅에서 사용한 툴, 라이브러리 IDE : STS4 Project : Gradle Project DB : H2 필요 라이브러리 추가 의존성 추가 (dependencies) build.gradle dependencies { implementation 'org.springframework.boot:spring-b

luvris2.tistory.com

 

반응형