Spring JDBC操作Oracle含$列时SQL类型未知问题求解
解决Spring JDBC操作Oracle带$符号列的SQL类型未知问题
问题根源是当参数为null时,Spring JDBC的StatementCreatorUtils无法通过数据库元数据正确识别带$符号列的SQL类型,导致类型推断失败。以下是几种可行的解决方法:
1. 显式指定参数SQL类型
在使用JdbcTemplate执行插入时,直接指定每个参数对应的SQL类型,绕过自动推断逻辑:
String insertSql = "INSERT INTO \"address\" (\"id\", \"SOURCE_CHANGE_TIME$\", \"full_address\") VALUES (?, ?, ?)"; jdbcTemplate.update(insertSql, new Object[]{address.getId(), address.getSourceChangeTime(), address.getFullAddress()}, new int[]{Types.BIGINT, Types.TIMESTAMP_WITH_TIMEZONE, Types.VARCHAR} );
- 这里
Types.TIMESTAMP_WITH_TIMEZONE对应Oracle中存储Instant的合适类型,若你的数据库用的是普通TIMESTAMP类型,替换为Types.TIMESTAMP即可。
2. 使用@SqlType注解显式指定字段SQL类型
如果你基于Spring Data JDBC开发,可以直接在实体类字段上添加@SqlType注解,明确该字段对应的SQL类型:
@Data public class BaseDwhEntity<ID> implements Serializable, Persistable<ID> { @Id @Column("id") private ID id; @Column("SOURCE_CHANGE_TIME$") @SqlType(Types.TIMESTAMP_WITH_TIMEZONE) // 显式绑定SQL类型 private Instant sourceChangeTime; @Override public boolean isNew() { return true; } // equals & hashCode 实现 }
Spring Data JDBC会直接使用注解指定的SQL类型,不再依赖数据库元数据推断。
3. 用NamedParameterJdbcTemplate配合MapSqlParameterSource指定类型
偏好命名参数风格的话,通过MapSqlParameterSource添加参数时显式声明类型:
String insertSql = "INSERT INTO \"address\" (\"id\", \"SOURCE_CHANGE_TIME$\", \"full_address\") VALUES (:id, :sourceChangeTime, :fullAddress)"; MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("id", address.getId(), Types.BIGINT); params.addValue("sourceChangeTime", address.getSourceChangeTime(), Types.TIMESTAMP_WITH_TIMEZONE); params.addValue("fullAddress", address.getFullAddress(), Types.VARCHAR); namedParameterJdbcTemplate.update(insertSql, params);
以上方法都能绕过Spring JDBC对带特殊字符列的元数据推断问题,强制指定正确的SQL类型,解决插入时的"SQL type unknown"错误。
内容的提问来源于stack exchange,提问作者R1zen
相关产品推荐
相关产品推荐

