Oracle ARRAY在MyBatis中报“invalid name pattern”根本原因是未手动实现TypeHandler且未正确获取OracleConnection、未带schema前缀注册类型名。
Oracle ARRAY类型在MyBatis里为什么总报“invalid name pattern”
根本原因是mybatis默认不识别oracle.sql.array,也没内置对应typehandler;你直接传string[]或list进去,驱动层会尝试用jdbc标准方式处理,而oracle驱动要求显式注册自定义sql类型名(比如schema.typename),否则抛java.sql.sqlexception: invalid name pattern。
- 必须手动实现
TypeHandler,且重写setParameter和getResult(后者通常用不到) -
setParameter里要通过Connection获取OracleConnection,再调用createARRAY——不能用getConnection().createArrayOf(...)(那是PostgreSQL/SQL Server的) - 类型名必须带schema前缀,比如
HR.STRING_ARRAY,大小写敏感,且该type需已在数据库中创建(CREATE TYPE STRING_ARRAY AS TABLE OF VARCHAR2(100)) - Mapper XML中参数要用
#{param, jdbcType=OTHER, javaType=string[], typeHandler=YourArrayHandler},jdbcType=OTHER不可省略
怎么写一个能用的Oracle ARRAY TypeHandler
别继承BaseTypeHandler搞泛型绕弯子,直接实现TypeHandler<string></string>最稳。关键点不在逻辑复杂,而在拿到正确的OracleConnection实例。
- 构造函数接收schema+type名称,比如
"HR"和"STRING_ARRAY",拼成typeName = schema + "." + typeName -
setParameter里用PreparedStatement.unwrap(OraclePreparedStatement.class)或更稳妥的ps.getConnection().unwrap(OracleConnection.class) - 数组元素必须是可被Oracle识别的Java类型:
String[]、Integer[]、BigDecimal[],不能传List或自定义对象 - 示例片段:
OracleConnection oc = ps.getConnection().unwrap(OracleConnection.class); ARRAY array = new ARRAY(oc.createDescriptor(typeName, oc), oc, value); ps.setObject(i, array);
MyBatis配置时最容易漏掉的三个地方
写了Handler、建了DB Type、写了Mapper,还是报错?大概率卡在这三处。
- 没在
mybatis-config.xml或Spring Boot的@Configuration里注册Handler:<typehandlers><typehandler handler="com.example.OracleStringArrayHandler" javatype="[Ljava.lang.String;" jdbctype="OTHER"></typehandler></typehandlers> - Mapper接口方法参数没加
@Param注解,导致XML里#{xxx}找不到绑定目标(尤其多参数时) - Oracle JDBC驱动版本太低(如ojdbc6),不支持某些ARRAY操作;必须用
ojdbc8(对应JDK 8+)或ojdbc11(JDK 11+)
存储过程调用时参数顺序和IN/OUT方向的影响
Oracle存储过程如果同时有IN ARRAY和OUT NUMBER,MyBatis的{call ...}语法对顺序极其敏感——哪怕XML里写对了,JDBC驱动仍可能因注册顺序错乱导致ORA-01008: not all variables bound。
- 务必按存储过程定义的**严格顺序**声明参数,
IN在前,OUT在后,中间不能插INOUT -
OUT参数必须用jdbcType明确指定,比如jdbcType=NUMERIC,不能只写jdbcType=OTHER - 调用语句建议用命名参数形式:
{call pkg.proc_name( #{inArray, mode=IN, jdbcType=OTHER, javaType=string[], typeHandler=OracleStringArrayHandler}, #{outResult, mode=OUT, jdbcType=NUMERIC} )}
Connection没正确unwrap成OracleConnection,或者type name少写了schema。这些地方一错,错误信息根本不提示真实原因。


















