반응형
예제 파일
https://github.com/luvris2/spring-boot-jap-nativequery
서론
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
반응형