在Java中的ibatis和oracle中传递并返回自定义数组对象
时间:2020-03-06 14:44:57 来源:igfitidea点击:
我一直在寻找一个很好的例子,但是我还没有碰到一个例子。我想使用IBATIS框架将自定义字符串数组从java传递到oracle,然后再传递回来。有人能很好地链接到示例吗?我正在从IBATIS调用存储的proc。
谢谢
解决方案
我们必须从TypeHandler的自定义实例开始。我们希望实现更简单的TypeHandlerCallback,但是在这种情况下,我们需要访问底层的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(); } ... }
然后,将其连接到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>
希望这可以帮助!
bsanders为我提供了一个很好的起点,这是使它在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); } }
注意,我必须获取native native,必须创建描述符,依此类推。但是,尽管我可以将它们作为字符串数组传递到数据库中,但我仍无法弄清为什么我什么也得不到。即使我在数据库的plsql中设置了out参数,我的OUT参数(getResult(CallableStatement statement,int i)也会抛出空指针异常。
--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;
这是我的访问方式:
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>
有任何想法吗?
尝试使用statement.getObject(i)
,然后转换为数组。