项目最开始时,是通过java代码中,增加事务@Transactional(value = "transactionManager")标识,然后在一个方法中,进行多次数据库操作。但是在代码评审的时候,领导说这种方式在数据量过大的情况下,可能会造成数据库卡死的情况, 让我进行优化。然后就开始了我的刨坑之旅。
首先,在网上找到了一篇文章https://blog.csdn.net/hzw2312/article/details/8444462,写的很清楚,然后就理所当然的搬到了项目中,并且测试通过,成功。
接下来神坑来啦,但是好多方法和对象全是“Deprecated”,然后就开始了我的填坑之旅。
老版代码如下:
oracle中创建自定影type,来对应pojo
CREATE OR REPLACE TYPE BLACKLIST_OBJECT AS object ( BLGUID VARCHAR2(32), NEEAID NVARCHAR2(8), LASTNAME VARCHAR2(64), FIRSTNAME VARCHAR2(64), DOB VARCHAR2(64), NATIONALID VARCHAR2(32), SRC VARCHAR2(8), EXPIRATIONTIME VARCHAR2(64), CPR VARCHAR2(512), RESTRICTSTATUS NUMBER )
然后再创建对应的Array对象
CREATE OR REPLACE TYPE BLACKLIST_OBJECT_ARRAY AS TABLE OF BLACKLIST_OBJECT
java代码:
1 private ARRAY getOracleArray(Connection con, String OraObjType, String OraArrType, List<BlacklistVo> blacklistVoList) 2 throws Exception { 3 ARRAY list = null; 4 ArrayDescriptor desc = ArrayDescriptor.createDescriptor(OraArrType, con); 5 if (blacklistVoList != null && blacklistVoList.size() > 0) { 6 // Oracle识别的集合对象,匹配java对象集合 7 STRUCT[] structs = new STRUCT[blacklistVoList.size()]; 8 // Oracle识别的对象模板,匹配单个java对象 9 StructDescriptor structdesc = new StructDescriptor(OraObjType, con); 10 // 遍历stuList,将每个Student对象转换为Oracle可识别的模板对象 11 for (int i = 0; i < blacklistVoList.size(); i++) { 12 // java对象 13 BlacklistVo blacklistVo = blacklistVoList.get(i); 14 // 数组大小应和你定义的数据库对象(STUDENT)的属性的个数 15 int index = 0; 16 Object[] oneRow = new Object[10]; 17 // 将Student对象的每个属性按顺序设置到oneRow数组中 18 oneRow[index++] = blacklistVo.getBlGuid(); 19 oneRow[index++] = blacklistVo.getNeeaId(); 20 oneRow[index++] = blacklistVo.getLastName(); 21 oneRow[index++] = blacklistVo.getFirstName(); 22 oneRow[index++] = blacklistVo.getDobStr(); 23 oneRow[index++] = blacklistVo.getNationalId(); 24 oneRow[index++] = blacklistVo.getSrc(); 25 oneRow[index++] = blacklistVo.getExpirationTimeStr(); 26 oneRow[index++] = blacklistVo.getCpr(); 27 oneRow[index++] = blacklistVo.getRestrictStatus(); 28 structs[i] = new STRUCT(structdesc, con, oneRow); 29 } 30 // 匹配list 31 list = new ARRAY(desc, con, structs); 32 } else { 33 STRUCT[] structs = new STRUCT[0]; 34 list = new ARRAY(desc, con, structs); 35 } 36 return list; 37 }
此时,上述代码虽然满足了需求,但是idea会提示Deprecated。
后来经过参考
https://www.oracle.com/cn/database/technologies/faq-jdbc.html#09_01
http://ask.sov5.cn/q/X8ghNRIAGx
将代码修改如下:
注意:
Connection一定要是OracleConnection
OracleConnection connection = getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class);
// 该函数调用的第二三个参数就是上面自定义的两个类型,在此必须大写
1 private Array getArray(OracleConnection con, String OraObjType, String OraArrType, List<BlacklistVo> blacklistVoList) 2 throws Exception { 3 Array list = null; 4 if (blacklistVoList != null && blacklistVoList.size() > 0) { 5 // Oracle识别的集合对象,匹配java对象集合 6 Struct[] structs = new Struct[blacklistVoList.size()]; 7 // 遍历stuList,将每个Student对象转换为Oracle可识别的模板对象 8 for (int i = 0; i < blacklistVoList.size(); i++) { 9 // java对象 10 BlacklistVo blacklistVo = blacklistVoList.get(i); 11 // 数组大小应和你定义的数据库对象(STUDENT)的属性的个数 12 int index = 0; 13 Object[] blacklistObject = new Object[10]; 14 // 将Student对象的每个属性按顺序设置到oneRow数组中 15 blacklistObject[index++] = blacklistVo.getBlGuid(); 16 blacklistObject[index++] = blacklistVo.getNeeaId(); 17 blacklistObject[index++] = blacklistVo.getLastName(); 18 blacklistObject[index++] = blacklistVo.getFirstName(); 19 blacklistObject[index++] = blacklistVo.getDobStr(); 20 blacklistObject[index++] = blacklistVo.getNationalId(); 21 blacklistObject[index++] = blacklistVo.getSrc(); 22 blacklistObject[index++] = blacklistVo.getExpirationTimeStr(); 23 blacklistObject[index++] = blacklistVo.getCpr(); 24 blacklistObject[index++] = blacklistVo.getRestrictStatus(); 25 structs[i] = con.createStruct(OraObjType, blacklistObject); 26 } 27 // 匹配list 28 list = con.createOracleArray(OraArrType, structs); 29 30 } else { 31 Struct[] structs = new Struct[0]; 32 list = con.createOracleArray(OraArrType, structs); 33 } 34 return list; 35 }
虽然就是些许改动,但是资料太少了,找了好久,还是自己摸索出来的,特此记录一下。