복붙노트

[SQL] Java 및 JPA에서 저장 프로 시저를 호출하는 방법

SQL

Java 및 JPA에서 저장 프로 시저를 호출하는 방법

내가 저장 프로 시저를 호출하고 일부 데이터를 검색하는 간단한 웹 응용 프로그램을 쓰고 있어요. 고객의 데이터베이스와 상호 작용 그것의 매우 간단한 응용 프로그램. 우리는 직원의 ID와 회사 ID 및 직원 정보를 반환 저장 프로 시저를 전달합니다.

/ 삭제 데이터와 SQL 서버를 사용을 업데이트 할 수 없습니다 웹 응용 프로그램입니다.

나는 제이 보스 AS 내 웹 응용 프로그램을 배포하고있다. 내가 저장 프로 시저 또는 CallableStatement로 액세스 할 수 JPA를 사용해야합니다. 이 경우 JPA를 사용하는 모든 장점.

또한이 저장 프로 시저를 호출하는 SQL 문을 일 무슨. 내가 전에 저장 프로 시저를 사용한 적이 그리고 난이 하나 고민하고 있습니다. 구글은 도움이 많이되지 않았습니다.

다음은 저장 프로 시저입니다 :

CREATE procedure getEmployeeDetails (@employeeId int, @companyId int)
as
begin
    select firstName, 
           lastName, 
           gender, 
           address
      from employee et
     where et.employeeId = @employeeId
       and et.companyId = @companyId
end

최신 정보:

다른 사람이 문제가 들어 JPA를 사용하여 저장 프로 시저를 호출합니다.

Query query = em.createNativeQuery("{call getEmployeeDetails(?,?)}",
                                   EmployeeDetails.class)           
                                   .setParameter(1, employeeId)
                                   .setParameter(2, companyId);

List<EmployeeDetails> result = query.getResultList();

상황이 내가 발견했습니다 :

해결법

  1. ==============================

    1.JPA 2.1 지금 저장 지원 절차, 여기에 자바 문서를 참조하십시오.

    JPA 2.1 지금 저장 지원 절차, 여기에 자바 문서를 참조하십시오.

    예:

    StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("sales_tax");
    // set parameters
    storedProcedure.registerStoredProcedureParameter("subtotal", Double.class, ParameterMode.IN);
    storedProcedure.registerStoredProcedureParameter("tax", Double.class, ParameterMode.OUT);
    storedProcedure.setParameter("subtotal", 1f);
    // execute SP
    storedProcedure.execute();
    // get result
    Double tax = (Double)storedProcedure.getOutputParameterValue("tax");
    

    여기에서 자세한 예를 참조하십시오.

  2. ==============================

    2.정말 JPA 지원하지 않습니다하지만 해 드리겠습니다. 그럼에도 불구하고 나는이 길을 갈 것입니다 :

    정말 JPA 지원하지 않습니다하지만 해 드리겠습니다. 그럼에도 불구하고 나는이 길을 갈 것입니다 :

    따라서 나는 오히려 응용 프로그램, 원시 JDBC와 CallableStatement로의 단순 주어진 JDBC 데이터 액세스, 또는 MyBatis로 같은 데이터 매퍼 나에 대한 스프링 지원을 사용하는 것이 좋습니다 것입니다. 사실, JDBC는 아마 내 선택이 될 것입니다. 여기에 기본 킥오프 예입니다 :

    CallableStatement cstmt = con.prepareCall("{call getEmployeeDetails(?, ?)}");
    cstmt.setInt("employeeId", 123);
    cstmt.setInt("companyId", 456);
    ResultSet rs = cstmt.executeQuery();
    
  3. ==============================

    3.당신은 저장 프로 시저에 매개 변수를 전달해야합니다.

    당신은 저장 프로 시저에 매개 변수를 전달해야합니다.

    그것은 다음과 같이 작동합니다 :

        List result = em
          .createNativeQuery("call getEmployeeDetails(:employeeId,:companyId)")
          .setParameter("emplyoyeeId", 123L)
          .setParameter("companyId", 456L)
          .getResultList();
    

    최신 정보:

    아니면 그것은 안된다.

    액션의 책 EJB3에서는, 책 전체가이 일을 포함하여 여러 곳에서 다운로드 할 수있는 페이지를 미리보기로, 당신은 전체 텍스트를하지 않는 것입니다 (JPA는 저장 프로 시저를 지원하지 않는 페이지 383에 말한다 이 법률하지만 경우에, 나는) 모르겠어요.

    어쨌든, 텍스트이 있습니다 :

  4. ==============================

    4.이 답변은 저장 프로 시저에서 레코드를 반환에 정교한 않는다하더라도, 그것을 알아 내기 위해 나에게 나이를 가져다가이 스레드 나에게 도움이 때문에, 여기에 게시하고있다.

    이 답변은 저장 프로 시저에서 레코드를 반환에 정교한 않는다하더라도, 그것을 알아 내기 위해 나에게 나이를 가져다가이 스레드 나에게 도움이 때문에, 여기에 게시하고있다.

    내 응용 프로그램은 EclipseLink-2.3.1를 사용했다,하지만 난에 업그레이드를 강제로 EclipseLink가-2.5.0, 2.1 저장 프로 시저에 대한 더 나은 지원을하고있다 JPA로.

    이 방법은 "org.eclipse.persistence"에서 EclipseLink가 클래스의 수입을 요구, 그래서는 EclipseLink 구현에 따라 다릅니다.

    나는 "http://www.yenlo.nl/en/calling-oracle-stored-procedures-from-eclipselink-with-multiple-out-parameters"에 그것을 발견했다.

    StoredProcedureCall storedProcedureCall = new StoredProcedureCall();
    storedProcedureCall.setProcedureName("mypackage.myprocedure");
    storedProcedureCall.addNamedArgument("i_input_1"); // Add input argument name.
    storedProcedureCall.addNamedOutputArgument("o_output_1"); // Add output parameter name.
    DataReadQuery query = new DataReadQuery();
    query.setCall(storedProcedureCall);
    query.addArgument("i_input_1"); // Add input argument names (again);
    List<Object> argumentValues = new ArrayList<Object>();
    argumentValues.add("valueOf_i_input_1"); // Add input argument values.
    JpaEntityManager jpaEntityManager = (JpaEntityManager) getEntityManager();
    Session session = jpaEntityManager.getActiveSession();
    List<?> results = (List<?>) session.executeQuery(query, argumentValues);
    DatabaseRecord record = (DatabaseRecord) results.get(0);
    String result = String.valueOf(record.get("o_output_1")); // Get output parameter
    

    이 방법은 (Eclipslink 수입이 필요하지 않습니다) 구현에 독립적이다.

    StoredProcedureQuery query = getEntityManager().createStoredProcedureQuery("mypackage.myprocedure");
    query.registerStoredProcedureParameter("i_input_1", String.class, ParameterMode.IN);
    query.registerStoredProcedureParameter("o_output_1", String.class, ParameterMode.OUT);
    query.setParameter("i_input_1", "valueOf_i_input_1");
    boolean queryResult = query.execute();
    String result = String.valueOf(query.getOutputParameterValue("o_output_1"));
    
  5. ==============================

    5.나를 위해, 오직 다음은 오라클 11g와 글래스 피시 2.1 (상단 링크)와 함께 일 :

    나를 위해, 오직 다음은 오라클 11g와 글래스 피시 2.1 (상단 링크)와 함께 일 :

    Query query = entityManager.createNativeQuery("BEGIN PROCEDURE_NAME(); END;");
    query.executeUpdate();
    

    중괄호를 가진 변형 ORA-00900 결과.

  6. ==============================

    6.은 EclipseLink를 사용하는 경우에는 출력 매개 변수를 가진 사람, 또는 커서에서 포함하여 모든 저장 프로 시저를 실행하기 위해 @NamedStoredProcedureQuery 또는 StoreProcedureCall를 사용할 수 있습니다. 저장 기능과 PLSQL의 데이터 유형에 대한 지원도 가능합니다.

    은 EclipseLink를 사용하는 경우에는 출력 매개 변수를 가진 사람, 또는 커서에서 포함하여 모든 저장 프로 시저를 실행하기 위해 @NamedStoredProcedureQuery 또는 StoreProcedureCall를 사용할 수 있습니다. 저장 기능과 PLSQL의 데이터 유형에 대한 지원도 가능합니다.

    보다, http://en.wikibooks.org/wiki/Java_Persistence/Advanced_Topics#Stored_Procedures

  7. ==============================

    7.JPA와 최대 절전 모드를 사용하여 저장 프로 시저 및 함수를 호출하는 방법에 대한 자세한 내용은 다음 문서를 체크 아웃

    JPA와 최대 절전 모드를 사용하여 저장 프로 시저 및 함수를 호출하는 방법에 대한 자세한 내용은 다음 문서를 체크 아웃

  8. ==============================

    8.다음은 나를 위해 작동합니다 :

    다음은 나를 위해 작동합니다 :

    Query query = em.createNativeQuery("BEGIN VALIDACIONES_QPAI.RECALC_COMP_ASSEMBLY('X','X','X',0); END;");
    query.executeUpdate();
    
  9. ==============================

    9.이 SQL Server의 경우하지만, Oracle을 사용하는 사람들을위한 동일 하하고 나를 위해 그것을의 작업을 EclipseLink가있다

    이 SQL Server의 경우하지만, Oracle을 사용하는 사람들을위한 동일 하하고 나를 위해 그것을의 작업을 EclipseLink가있다

    예 : 하나에 PARAM (유형 CHAR)와 두 개의 OUT의 PARAMS이 절차 (NUMBER 및 VARCHAR)

    persistence.xml을 상기 지속성 유닛 선언

    <persistence-unit name="presistanceNameOfProc" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/DataSourceName</jta-data-source>
        <mapping-file>META-INF/eclipselink-orm.xml</mapping-file>
        <properties>
            <property name="eclipselink.logging.level" value="FINEST"/>
            <property name="eclipselink.logging.logger" value="DefaultLogger"/>
            <property name="eclipselink.weaving" value="static"/>
            <property name="eclipselink.ddl.table-creation-suffix" value="JPA_STORED_PROC" />
        </properties>
    </persistence-unit>
    

    상기는 EclipseLink-orm.xml에서 PROC의 구조를 선언

    <?xml version="1.0" encoding="UTF-8"?><entity-mappings version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd">
    <named-stored-procedure-query name="PERSIST_PROC_NAME" procedure-name="name_of_proc" returns-result-set="false">
        <parameter direction="IN" name="in_param_char" query-parameter="in_param_char" type="Character"/>
        <parameter direction="OUT" name="out_param_int" query-parameter="out_param_int" type="Integer"/>
        <parameter direction="OUT" name="out_param_varchar" query-parameter="out_param_varchar" type="String"/>
    </named-stored-procedure-query>
    

    코드에서 당신은이처럼 시저를 호출 할 수 있습니다 :

    try {
            final Query query = this.entityManager
                    .createNamedQuery("PERSIST_PROC_NAME");
            query.setParameter("in_param_char", 'V'); 
            resultQuery = (Object[]) query.getSingleResult();
    
        } catch (final Exception ex) {
            LOGGER.log(ex);
            throw new TechnicalException(ex);
        }
    

    두 개의 출력 PARAMS을 얻을 수 있습니다 :

    Integer myInt = (Integer) resultQuery[0];
    String myStr =  (String) resultQuery[1];
    
  10. ==============================

    10.이것은 나를 위해 일했다.

    이것은 나를 위해 일했다.

    @Entity
    @Table(name="acct")
    @NamedNativeQueries({
     @NamedNativeQuery(callable=true, name="Account.findOne", query="call sp_get_acct(?), resultClass=Account.class)})
    public class Account{
     // Code 
    }
    

    참고 : findOne의 기본 버전을 사용하기로 결정한 경우 미래에 다음 바로 NamedNativeQueries 주석을 언급하고 JPA는 기본적으로 전환됩니다

  11. ==============================

    11.당신은 엔티티 관리자가있는 경우이 답변이 도움이 될 수

    당신은 엔티티 관리자가있는 경우이 답변이 도움이 될 수

    나는 다음 번호를 만들 수있는 저장 프로 시저를했고, 서버 측에서 나는 심 프레임 워크를 가지고있다.

    고객 입장에서

     Object on = entityManager.createNativeQuery("EXEC getNextNmber").executeUpdate();
            log.info("New order id: " + on.toString());
    

    getNextNmber라는 이름의 데이터베이스 측면 (SQL 서버) 내가 저장 한 절차

  12. ==============================

    12.JPA 2.0 반환 값을 지원하지 않는 호출 만.

    JPA 2.0 반환 값을 지원하지 않는 호출 만.

    내 솔루션이었다. 함수 호출 프로 시저를 만듭니다.

    그래서, 자바 코드 내에서 당신은 오라클 함수를 호출 기본 QUERY를 실행합니다.

  13. ==============================

    13.저장 프로 시저를 호출하려면 우리는 java.sql의 패키지에 호출 가능 문을 사용할 수 있습니다.

    저장 프로 시저를 호출하려면 우리는 java.sql의 패키지에 호출 가능 문을 사용할 수 있습니다.

  14. ==============================

    14.이 코드를보십시오 :

    이 코드를보십시오 :

    return em.createNativeQuery("{call getEmployeeDetails(?,?)}",
                                   EmployeeDetails.class)           
                                   .setParameter(1, employeeId)
                                   .setParameter(2, companyId).getResultList();
    
  15. ==============================

    15.당신은 @query 사용할 수 있습니다 (값 = "{호출 PROC_TEST ()}"= 사실 nativeQuery) 저장소한다. 이것은 나를 위해 일했다.

    당신은 @query 사용할 수 있습니다 (값 = "{호출 PROC_TEST ()}"= 사실 nativeQuery) 저장소한다. 이것은 나를 위해 일했다.

    주의 : 사용 '{'와 '}'그렇지 않으면 작동하지 않습니다.

  16. ==============================

    16.이 persistence.xml

    이 persistence.xml

     <persistence-unit name="PU2" transaction-type="RESOURCE_LOCAL">
    <non-jta-data-source>jndi_ws2</non-jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
    

    자바 코드

      String PERSISTENCE_UNIT_NAME = "PU2";
        EntityManagerFactory factory2;
        factory2 = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    
        EntityManager em2 = factory2.createEntityManager();
        boolean committed = false;
        try {
    
            try {
                StoredProcedureQuery storedProcedure = em2.createStoredProcedureQuery("PKCREATURNO.INSERTATURNO");
                // set parameters
                storedProcedure.registerStoredProcedureParameter("inuPKEMPRESA", BigDecimal.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("inuPKSERVICIO", BigDecimal.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("inuPKAREA", BigDecimal.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("isbCHSIGLA", String.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("INUSINCALIFICACION", BigInteger.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("INUTIMBRAR", BigInteger.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("INUTRANSFERIDO", BigInteger.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("INTESTADO", BigInteger.class, ParameterMode.IN);
                storedProcedure.registerStoredProcedureParameter("inuContador", BigInteger.class, ParameterMode.OUT);
    
                BigDecimal inuPKEMPRESA = BigDecimal.valueOf(1);
                BigDecimal inuPKSERVICIO = BigDecimal.valueOf(5);
                BigDecimal inuPKAREA = BigDecimal.valueOf(23);
                String isbCHSIGLA = "";
                BigInteger INUSINCALIFICACION = BigInteger.ZERO;
                BigInteger INUTIMBRAR = BigInteger.ZERO;
                BigInteger INUTRANSFERIDO = BigInteger.ZERO;
                BigInteger INTESTADO = BigInteger.ZERO;
                BigInteger inuContador = BigInteger.ZERO;
    
                storedProcedure.setParameter("inuPKEMPRESA", inuPKEMPRESA);
                storedProcedure.setParameter("inuPKSERVICIO", inuPKSERVICIO);
                storedProcedure.setParameter("inuPKAREA", inuPKAREA);
                storedProcedure.setParameter("isbCHSIGLA", isbCHSIGLA);
                storedProcedure.setParameter("INUSINCALIFICACION", INUSINCALIFICACION);
                storedProcedure.setParameter("INUTIMBRAR", INUTIMBRAR);
                storedProcedure.setParameter("INUTRANSFERIDO", INUTRANSFERIDO);
                storedProcedure.setParameter("INTESTADO", INTESTADO);
                storedProcedure.setParameter("inuContador", inuContador);
    
                // execute SP
                storedProcedure.execute();
                // get result
    
                try {
                    long _inuContador = (long) storedProcedure.getOutputParameterValue("inuContador");
                    varCon = _inuContador + "";
                } catch (Exception e) {
                } 
            } finally {
    
            }
        } finally {
            em2.close();
        }
    
  17. ==============================

    17.JPA 2.1, JPA를 지원하는 동적 StoredProcedureQuery 및 @NamedStoredProcedureQuery 선언을 이용하여 프로 시저를 호출한다.

    JPA 2.1, JPA를 지원하는 동적 StoredProcedureQuery 및 @NamedStoredProcedureQuery 선언을 이용하여 프로 시저를 호출한다.

  18. ==============================

    18.내 솔루션이었다. 함수 호출 프로 시저를 만듭니다.

    내 솔루션이었다. 함수 호출 프로 시저를 만듭니다.

    그래서, 자바 코드 내에서 당신은 오라클 함수를 호출 기본 QUERY를 실행합니다.

  19. from https://stackoverflow.com/questions/3572626/how-to-call-a-stored-procedure-from-java-and-jpa by cc-by-sa and MIT license