1. 소개

이 빠른 사용방법(예제)에서는 JPA (Java Persistence API) 내에서 저장 프로 시저를 사용하는 방법을 살펴 봅니다.

2. 프로젝트 설정

2.1. Maven 설정

먼저 pom.xml에 다음 의존성을 정의해야합니다 .

  • javax.javaee-api – JPA API 포함
  • JPA API 구현 –이 예제에서는 Hibernate 를 사용 하지만 EclipseLink도 괜찮은 대안이 될 것입니다.
  • MySQL의 데이터베이스
<properties>
    <jee.version>7.0</jee.version>
    <mysql.version>11.2.0.4</mysql.version>
    <hibernate.version>5.1.38</hibernate.version>
</properties>
<dependencies>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>${jee.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
    </dependency>
</dependencies>

2.2. 지속성 단위 정의

두 번째 단계는 지속성 단위 정의를 포함하는 src / main / resources / META-INF / persistence.xml 파일을 만드는 것입니다.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd"
    version="2.1">

    <persistence-unit name="jpa-db">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>com.baeldung.jpa.model.Car</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" 
              value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" 
              value="jdbc:mysql://127.0.0.1:3306/baeldung" />
            <property name="javax.persistence.jdbc.user" 
              value="baeldung" />
            <property name="javax.persistence.jdbc.password" 
              value="YourPassword" />
            <property name="hibernate.dialect" 
              value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>

</persistence>

JNDI DataSource (JEE 환경)를 참조하는 경우 정의 된 모든 Hibernate 속성은 필요하지 않습니다.

<jta-data-source>java:jboss/datasources/JpaStoredProcedure</jta-data-source>

2.3. 테이블 생성 스크립트

이제 ID, MODELYEAR의 세 가지 속성이 있는 테이블 (CAR)을 생성 해 보겠습니다 .

CREATE TABLE `car` (
  `ID` int(10) NOT NULL AUTO_INCREMENT,
  `MODEL` varchar(50) NOT NULL,
  `YEAR` int(4) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

물론 DB 스키마와 권한이 이미 존재한다고 가정했습니다.

2.4. DB에 저장 프로 시저 생성

자바 코드로 이동하기 전 마지막 단계는 MySQL 데이터베이스에서 저장 프로 시저를 생성하는 것입니다.

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `FIND_CAR_BY_YEAR`(in p_year int)
begin
SELECT ID, MODEL, YEAR
    FROM CAR
    WHERE YEAR = p_year;
end
$$
DELIMITER ;

3. JPA 저장 프로 시저

이제 JPA를 사용하여 데이터베이스와 통신하고 정의한 저장 프로 시저를 실행할 준비가되었습니다.

그렇게하면 결과를 List of Car 로 반복 할 수도 있습니다 .

3.1. 자동차 엔티티

엔티티 관리자에 의해 CAR 데이터베이스 테이블에 잘 매핑 되는 Car 엔티티 아래 .

또한 @NamedStoredProcedureQueries 어노테이션 을 사용하여 엔터티에서 직접 저장 프로 시저를 정의하고 있습니다 .

@Entity
@Table(name = "CAR")
@NamedStoredProcedureQueries({
  @NamedStoredProcedureQuery(
    name = "findByYearProcedure", 
    procedureName = "FIND_CAR_BY_YEAR", 
    resultClasses = { Car.class }, 
    parameters = { 
        @StoredProcedureParameter(
          name = "p_year", 
          type = Integer.class, 
          mode = ParameterMode.IN) }) 
})
public class Car {

    private long id;
    private String model;
    private Integer year;

    public Car(String model, Integer year) {
        this.model = model;
        this.year = year;
    }

    public Car() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false, scale = 0)
    public long getId() {
        return id;
    }

    @Column(name = "MODEL")
    public String getModel() {
        return model;
    }

    @Column(name = "YEAR")
    public Integer getYear() {
        return year;
    }
    
    // standard setter methods
}

3.2. 데이터베이스 액세스

이제 모든 것이 정의되고 제자리에 있으면 실제로 JPA를 사용하여 프로 시저를 실행하는 몇 가지 테스트를 작성해 보겠습니다.

우리는 주어진 연도모든 자동차 를 검색 할 것입니다 .

public class StoredProcedureTest {

    private static EntityManagerFactory factory = null;
    private static EntityManager entityManager = null;

    @BeforeClass
    public static void init() {
        factory = Persistence.createEntityManagerFactory("jpa-db");
        entityManager = factory.createEntityManager();
    }

    @Test
    public void findCarsByYearWithNamedStored() {
        StoredProcedureQuery findByYearProcedure = 
          entityManager.createNamedStoredProcedureQuery("findByYearProcedure");
        
        StoredProcedureQuery storedProcedure = 
          findByYearProcedure.setParameter("p_year", 2015);
        
        storedProcedure.getResultList()
          .forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear())); 
    }

    @Test
    public void findCarsByYearNoNamedStored() {
        StoredProcedureQuery storedProcedure = 
          entityManager
            .createStoredProcedureQuery("FIND_CAR_BY_YEAR",Car.class)
            .registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
            .setParameter(1, 2015);
       
        storedProcedure.getResultList()
          .forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear()));
    }

}

두 번째 테스트에서는 엔티티에 대해 정의한 저장 프로 시저를 더 이상 사용하지 않습니다 . 대신, 우리는 처음부터 절차를 정의하고 있습니다.

저장 프로 시저를 사용해야하지만 엔터티를 수정하고 다시 컴파일 할 수있는 옵션이 없을 때 매우 유용 할 수 있습니다.

4. 결론

이 사용방법(예제)에서는 Java Persistence API와 함께 저장 프로 시저를 사용하는 방법에 대해 설명했습니다.

이 문서에 사용 된 예제는 GitHub샘플 프로젝트 로 제공됩니다 .