向存储过程,传递数组或者list类型的in参数(ARRAY、createArray、createOracleArray)

  项目最开始时,是通过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代码:

  注意:

  Connection一定要是OracleConnection 
  OracleConnection connection = getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class);
 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

将代码修改如下:

    // 该函数调用的第二三个参数就是上面自定义的两个类型,在此必须大写
 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     }

  虽然就是些许改动,但是资料太少了,找了好久,还是自己摸索出来的,特此记录一下。

  


原文地址:https://www.cnblogs.com/hobby0524/p/14510265.html