ストアドプロシージャにアクセスするためのJDBCに関する質問

最近のアプリケーションを開発し、ストアドプロシージャのリストのための参照に呼び出す必要があります。

ストアドプロシージャ:proc_test(P1 OUT数、数はP2、TAB_CUSTOMER P3において)。

次のようにこのタイプのリストは、カスタムオラクルのパラメータテーブルです:

TYP_CUSTOMER OF TABLE AS TYPEのTAB_CUSTOMERをCREATE OR REPLACE。

CREATE OR REPLACE TYPEのTYP_CUSTOMERをオブジェクトとして

  ID VARCHAR2(20)、
  NAME VARCHAR2(20)、
  GENDER番号、
  AGEのNUMBER、

 BIRTHDAYのDATE
);

一つの問題:OracleストアドプロシージャにListオブジェクトを渡す方法

間違ったタイプまたはパラメータの数:最初の私は@ProcedureのJPAを使用するには、結果がエラーとなっています。私はこのプロジェクトによ

これは、エンティティクラスのお客様は、Oracle、および同じタイプのTYP_CUSTOMERのフィールドを定義します。合格

ストアドプロシージャの一覧<顧客>。java.util.Listには、必要な手続きを保存するoracle.sql.ARRAYオブジェクトに変換することはできません。

次のようにその後、彼は、同僚や関連する経験、問題解決の相談しました:

[ストアドプロシージャをするoracle.sql.ARRAY渡す方法の問題点を解決するために以下のコードは】

輸入はjava.util.List;
インポートのjava.sql.Connection;
インポートするoracle.sql.ARRAY;
輸入oracle.sql.ArrayDescriptor;
インポートのoracle.sql.STRUCT;
輸入oracle.sql.StructDescriptor;
輸入oracle.sql.DATE;

/ *
    以下の方法は、Oracleカスタムとoracle.sql.ARRAYオブジェクトを返す
    テーブルマッピングオブジェクト。
    @param oracleTypeオラクルのカスタムクラスの
    テーブル@param oracleTableオラクルのカスタムクラス
    のローカルパッケージリストデータ@list
    @return・アレイは、Oracleでカスタマイズすることができoracle.sql.ARRAYオブジェクト
    のオブジェクト表をマッピング。
* /
プライベートARRAYは、getOracleArray(CON接続、OracleType文字列、文字列oracleTable、リスト<顧客>リスト)
            例外{スロー
        配列array = NULLを、
        識別するArrayDescriptor DESC =は、ArrayDescriptor.createDescriptor(oracleTable、CON);
        STRUCT [] =新しい新しい構造体STRUCT [一覧.size()]。

        (もし!リスト= NULL &&はlist.size()> 0){
            にStructDescriptor structdesc =新にStructDescriptor(oracleType、CON);
            {(; iがLEN <I ++は、I = 0、LEN =はlist.size()INT)のための
                オブジェクト[]結果= {
                        list.get(I).getId()、
                        list.get(I).getName()、
                        list.get(I).getGender()、
                        list.get(I).getAge()、
                        新しいDATE}(新しいjava.sql.Date(list.get(I).getBirthday()getTime()));
                構造体[I] =新しいSTRUCT(structdesc、CON、結果)。
            }
            アレイ=新しい配列(DESC、CON、構造体)。
        }他{
            配列=新しいアレイ(DESC、CON、構造体)。
        }
        の配列を返します。
    }

輸入java.util.Date;
クラス顧客{
    int型のID。
    文字列の名前。
    文字列の性別;
    int型の年齢;
    日付の誕生日。
    / *省略ゲッター/セッター* /
}

第二の問題:接続の最大数は、専用接続プールの要求を開始することができます

次のように問題のコードは次のとおりです。

@Autowired

private HikariDataSource hikariDataSource;

保存します。public void(一覧<顧客>顧客、int型のP2){
        接続CONN = NULL;
        試す{
            CONN =のgetConnection();

            PreparedStatementのてpstmt = conn.prepareStatement( "???PKG_TEST.PROC_TEST(、)を呼び出します");
            ARRAY P3 =は、getOracleArray(CONN、TYP_CUSTOMER、TAB_CUSTOMER、顧客);

            int型P1 = 0;
            pstmt.setInt(1、P1)。
            pstmt.setInt(2、P2)。
            pstmt.setArray(3、P3)。

            pstmt.execute();
            pstmt.close();
        }キャッチ(のSQLException E){
            新しいPersistException(e)を投げます。
        }キャッチ(例外e){
            新しいPersistException(e)を投げます。
        }最後に{
            場合(connの= nullを!)
                {しようと
                    はconn.closeを();
                }キャッチ(例外e){
                    新しいPersistException(e)を投げます。
                }
        }
    }
    
    プライベート接続のgetConnection(){
        接続CONN = NULL;
        試す{
            CONN = hikariDataSource.getConnection()。
            DatabaseMetaDataのmetaData = conn.getMetaData()。
            CONN = metaData.getConnection()。
        }キャッチ(のSQLException E){
            新しいPersistException(e)を投げます。
        }

        CONN返します。
    }

クラスPersistExceptionはのRuntimeExceptionを拡張{/ *省略* /}

ひかりの接続が直接キャストされていないのので、私は、HikariDataSourceにここにあります

Oracleの接続は、その上記の変換をしました。

データベースへの訪問が終了した後に、データベース接続が解除されていないことが表示されます。

テーブルのクエリは、同じ問題を抱えていることができます]

 

次のような問題を解決するためのコード:

輸入javax.persistence.EntityManager。
輸入javax.persistence.PersistenceContext;
輸入org.hibernate.engine.spi.SessionImplementor。

 

@PersistenceContext

民間のEntityManagerはEntityManager。

    (SaleRetrainingReportレポート)のセーブます。public void {
        {しようと
            接続CONN = entityManager.unwrap(SessionImplementor.class).connectionを();
            
            CallableStatementのstmt = conn.prepareCall( "PKG_TEST.PROC_TEST(、)を呼び出す???の");
            ARRAY P3 =は、getOracleArray(toOracleConnection(CONN)、TYP_CUSTOMER、TAB_CUSTOMER、顧客)。

            int型P1 = 0;
            stmt.setInt(1、P1)。
            stmt.setInt(2、P2)。
            stmt.setArray(3、P3)。

            でstmt.execute();
            stmt.close();
        }キャッチ(のSQLException E){
            新しいPersistException(e)を投げます。
        }キャッチ(例外e){
            新しいPersistException(e)を投げます。
        }
    }

    プライベート接続toOracleConnection(接続接続){
        接続CONN = NULL;
        試す{
            DatabaseMetaDataののmetaData = connection.getMetaData()。
            CONN = metaData.getConnection()。
        }キャッチ(のSQLException E){
            新しいPersistException(e)を投げます。
        }

        CONN返します。
    }

 

 

 

 

 
--------------------- 

おすすめ

転載: www.cnblogs.com/ly570/p/10977623.html