You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用MyBatis TypeHandler映射List<Dep>到Oracle数组时遇ORA-06550错误求助

排查MyBatis TypeHandler映射Oracle数组时的ORA-06550/PLS-00103错误

我之前也踩过Oracle数组映射的坑,结合你给出的代码片段,咱们来一步步拆解这个问题:

可能的错误原因

  1. 数据库类型与代码定义不匹配:你注释掉的StructDescriptor.createDescriptor("MEMS_ARR", connection)里的类型名,可能和Oracle数据库中实际定义的数组/结构体类型不一致(Oracle默认大小写敏感,注意要完全匹配)。
  2. 数组创建逻辑缺失:从截断的代码看,你只初始化了Struct[] structs但没有正确填充结构体,也没有创建Oracle原生的ARRAY对象,直接传递Struct数组会让Oracle无法识别参数类型。
  3. 未使用Oracle JDBC扩展:标准JDBC Connection没有创建Oracle数组的方法,必须强转为OracleConnection才能调用专属API。
  4. 代码语法错误:你代码里的parameter.si...明显是截断了,实际如果是拼写错误(比如少写ze),会导致参数长度计算错误,间接引发Oracle的参数解析异常。

解决办法

1. 先确认Oracle端的类型定义

必须先在数据库中定义对应的结构体和数组类型,比如:

-- 先定义对应Dep类的结构体类型
CREATE OR REPLACE TYPE DEP_TYPE AS OBJECT (
    dep_id NUMBER,
    dep_name VARCHAR2(100)
);
-- 再定义该结构体的数组类型
CREATE OR REPLACE TYPE MEMS_ARR AS TABLE OF DEP_TYPE;

确保代码里引用的类型名和这里的完全一致(比如MEMS_ARRDEP_TYPE都是大写)。

2. 修正TypeHandler的setParameter方法

补全逻辑并使用Oracle JDBC扩展API:

@Override
public void setParameter(PreparedStatement ps, int i, List<Dep> parameter, JdbcType jdbcType) throws SQLException {
    // 处理空参数的情况
    if (parameter == null || parameter.isEmpty()) {
        ps.setNull(i, Types.ARRAY, "MEMS_ARR");
        return;
    }

    // 强转为OracleConnection,调用专属API
    OracleConnection oracleConn = ps.getConnection().unwrap(OracleConnection.class);
    
    // 构建Struct数组(对应DEP_TYPE结构体)
    StructDescriptor structDesc = StructDescriptor.createDescriptor("DEP_TYPE", oracleConn);
    Struct[] structs = new Struct[parameter.size()];
    for (int idx = 0; idx < parameter.size(); idx++) {
        Dep dep = parameter.get(idx);
        // 按结构体属性顺序封装数据
        Object[] attributes = new Object[]{dep.getDepId(), dep.getDepName()};
        structs[idx] = new STRUCT(structDesc, oracleConn, attributes);
    }

    // 创建Oracle数组并设置到PreparedStatement
    ARRAY oracleArray = oracleConn.createARRAY("MEMS_ARR", structs);
    ps.setArray(i, oracleArray);
}

3. 检查MyBatis的Mapper配置

在XML或注解中明确指定参数的jdbcType和typeHandler:

XML方式:

<insert id="batchInsertDeps" parameterType="java.util.List">
    INSERT INTO your_table (dep_list_col)
    VALUES (#{depList, jdbcType=ARRAY, typeHandler=com.your.package.DepListTypeHandler})
</insert>

注解方式:

@Insert("INSERT INTO your_table (dep_list_col) VALUES (#{depList, jdbcType=ARRAY, typeHandler=com.your.package.DepListTypeHandler})")
void batchInsertDeps(@Param("depList") List<Dep> depList);

4. 修复代码语法问题

确保你实际代码里的parameter.si...是完整的parameter.size(),避免因语法错误导致参数传递异常。

内容的提问来源于stack exchange,提问作者osama yaccoub

火山引擎 最新活动