2008-09-25 12 views
7

He buscado un buen ejemplo de esto, pero todavía no me he encontrado con ninguno. Quiero pasar una matriz de cadenas personalizada de Java a Oracle y viceversa, utilizando el marco de IBATIS. ¿Alguien tiene un buen enlace a un ejemplo? Estoy llamando procs almacenados de IBATIS.Pase y devuelva un objeto de matriz personalizado en ibatis y oracle en java

Gracias

+0

¿qué es lo que quiere decir con un * Custom * matriz de cadenas, es esto de alguna manera diferente de String [] ? –

Respuesta

2

usted tiene que comenzar con una instancia de costumbre de TypeHandler. Preferiríamos implementar el más simple TypeHandlerCallback, pero en este escenario necesitamos acceso al subyacente Connection.

public class ArrayTypeHandler implements TypeHandler { 

    public void setParameter(PreparedStatement ps, int i, Object param, String jdbcType) 
      throws SQLException { 
     if (param == null) { 
      ps.setNull(i, Types.ARRAY); 
     } else { 
      Connection conn = ps.getConnection(); 
      Array loc = conn.createArrayOf("myArrayType", (Object[]) param); 
      ps.setArray(i, loc); 
     } 
    } 

    public Object getResult(CallableStatement statement, int i) 
      throws SQLException { 
     return statement.getArray(i).getArray(); 
    } 
    ... 
} 

Luego, para cablear en la configuración iBATIS:

<?xml version="1.0"?> 
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> 

<sqlMap namespace="arrayTest"> 

    <parameterMap id="storedprocParams" class="map"> 
     <parameter property="result" mode="OUT" jdbcType="ARRAY" typeHandler="ArrayTypeHandler"/> 
     <parameter property="argument" mode="IN" jdbcType="ARRAY" typeHandler="ArrayTypeHandler"/> 
    </parameterMap> 

    <procedure id="storedproc" parameterMap="arrayTest.storedprocParams"> 
     {? = call My_Array_Function(?)} 
    </procedure> 

</sqlMap> 

Espero que esto ayude!

+0

Este fue un buen punto de partida: tuve que obtener la conexión nativa de RAD, agregar un descriptor que describía mi matriz personalizada y asegurarme de que el objeto en la base de datos estuviera accesible. Mira lo que hice en la respuesta. – Justin

2

bsanders me dio un buen punto de partida, esto es lo que tuve que hacer para que funcione dentro del entorno RAD (websphere 6.2).

public Object getResult(CallableStatement statement, int i) throws SQLException { 
    return statement.getArray(i).getArray(); //getting null pointer exception here 
} 

public void setParameter(PreparedStatement ps, int i, Object param, String jdbcType) throws SQLException { 
    if (param == null) { 
     ps.setNull(i, Types.ARRAY); 

    } else { 
     String[] a = (String[]) param; 
     //ARRAY aOracle = ARRAY.toARRAY(a, (OracleConnection)ps.getConnection()); 

     //com.ibm.ws.rsadapter.jdbc.WSJdbcConnection 
     w = (com.ibm.ws.rsadapter.jdbc.WSJdbcConnection)ps.getConnection()); 

     //com.ibm.ws.rsadapter.jdbc.WSJdbcObject x; 
     Connection nativeConnection = Connection)WSJdbcUtil.getNativeConnection((WSJdbcConnection)ps.getConnection()); 

     ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("F2_LIST", nativeConnection); 
     ARRAY dataArray = new ARRAY(descriptor, nativeConnection, a); 
     ps.setArray(i, dataArray); 
    } 
} 

Observe la conexión nativa que tenía que obtener, el descriptor que tenía que hacer, y así sucesivamente. Sin embargo, aunque puedo pasar cosas a la base de datos como una matriz de cadenas, no he podido averiguar por qué no recibo nada. Mi parámetro OUT (la DECLARACIÓN getResult (CallableStatement, int i) es lanzar una excepción de puntero nulo, a pesar de que estoy estableciendo el parámetro en el plsql en la base de datos.

--stored procedure to take a | delimited ids 
    PROCEDURE array_test (argument IN f2_list, result OUT f2_list) 
    AS 
     l_procname_v VARCHAR2 (50)     := 'array_test'; 
     l_param_list VARCHAR2 (2000) 
        := l_procname_v || ' param_values: p_string: '; 

     p_status_n  NUMBER; 
     p_message_v VARCHAR2 (2000); 
     ret_list f2_list := new f2_list(); 
     l_count_v varchar2(200); 
    BEGIN 

     l_count_v := argument.COUNT; 
     for x in 1..argument.count 
     LOOP 
      pkg_az_common_util.az_debug (package_nm, 
            l_procname_v, 
            pkg_az_data_type_def.debug_num, 
            argument(x) 
           ); 
     end loop; 

     pkg_az_common_util.az_debug (package_nm, 
            l_procname_v, 
            pkg_az_data_type_def.debug_num, 
            l_count_v 
           ); 
     ret_list.extend(); 
     ret_list(1) := 'W'; 
     ret_list.extend(); 
     ret_list(2) := 'X'; 
     ret_list.extend(); 
     ret_list(3) := 'Y'; 
     ret_list.extend(); 
     ret_list(4) := 'Z'; 

     result := ret_list; 


    EXCEPTION 
     WHEN OTHERS 
     THEN 
     p_status_n := pkg_az_common_util.get_error_code; 
     p_message_v := 
       TO_CHAR (p_status_n) 
      || '|' 
      || 'Oracle Internal Exception(' 
      || l_procname_v 
      || ')' 
      || '|' 
      || TO_CHAR (SQLCODE) 
      || '|' 
      || SQLERRM 
      || l_param_list; 
     standard_pkg.log_error (package_nm, 
           l_procname_v, 
           SQLCODE, 
           p_message_v 
           ); 

     IF p_status_n = 1 
     THEN 
      RAISE; 
     END IF; 
    END array_test; 

Aquí es cómo estoy accediendo que:?.

Map queryParamsTest = new HashMap(); 

     String[] testArray = {"A", "B", "C"}; 

     queryParamsTest.put("argument", testArray); 



     DaoUtils.executeQuery(super.getSqlMapClientTemplate(), 
       "arrayTest", queryParamsTest, queryParamsTest 
       .toString()); //just executes query 


     String[] resultArray = (String[])queryParamsTest.get("result"); 

     for(int x = 0; x< resultArray.length; x++) 
     { 
      System.out.println("Result: " + resultArray[x]); 
     } 



<parameterMap id="storedprocParams" class="map">   
     <parameter property="argument" mode="IN" jdbcType="ARRAY" typeHandler="ArrayTypeHandler"/>  
     <parameter property="result" mode="OUT" jdbcType="ARRAY" typeHandler="ArrayTypeHandler"/>   
    </parameterMap>  
    <procedure id="arrayTest" parameterMap="storedprocParams">   
     {call pkg_az_basic_dev.array_test(?, ?)}  
    </procedure> 

Cualquier idea

0

Intente utilizar statement.getObject(i) y luego echando a un array

1

Bueno, chicos de la compañía descubrieron el solución: Es necesario tener implementado el método (s) getResult en su TypeHandler y proporcionado atributo adicional jdbcTypeName = ORACLE_REAL_ARRAY_TYPE en su mapeador

+0

noté que el tipo de ARRAY no se admite en la documentación de batis, encontré ese desinformativo – tomasb

Cuestiones relacionadas