You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SimpleJdbcInsert插入含枚举类型列的数据?

解决PostgreSQL自定义枚举类型插入失败问题

问题原因

JDBC默认会把字符串参数识别为varchar类型,而PostgreSQL不会自动将varchar转换为自定义枚举类型test_type,因此抛出类型不匹配错误。你之前尝试在字符串后加::test_type无效,是因为JDBC把整个字符串当成了字段值,而非SQL语法里的类型转换逻辑。

可行解决方案

方案一:用Java枚举对应数据库枚举(推荐,类型安全)

  1. 先定义和数据库test_type完全匹配的Java枚举(注意大小写要和数据库枚举值一致,PostgreSQL枚举大小写敏感):
public enum TestType {
    planning
    // 其他枚举值按需添加
}
  1. 修改插入代码,传入枚举实例并指定参数类型:
Map<String, Object> testRecord = new HashMap<>();
testRecord.put("name", "whatever");
testRecord.put("type", TestType.planning); // 传入枚举对象而非字符串

SimpleJdbcInsert insertTest = new SimpleJdbcInsert(jdbcTemplate)
    .withTableName("test_table")
    .usingColumns("name", "type") // 显式指定列名,避免keySet顺序问题
    .usingGeneratedKeyColumns("id");

// 关键:告诉JDBC该参数对应数据库枚举类型
SqlParameterSource parameters = new MapSqlParameterSource(testRecord)
    .registerSqlType("type", Types.OTHER);

Number testId = insertTest.executeAndReturnKey(parameters);

方案二:直接传字符串,显式声明参数类型

如果不想定义Java枚举,可以直接传字符串,但要声明参数的SQL类型为OTHER,让PostgreSQL识别为枚举:

Map<String, Object> testRecord = new HashMap<>();
testRecord.put("name", "whatever");
testRecord.put("type", "planning");

SimpleJdbcInsert insertTest = new SimpleJdbcInsert(jdbcTemplate)
    .withTableName("test_table")
    .usingColumns("name", "type")
    .usingGeneratedKeyColumns("id")
    .declareParameters(
        new SqlParameter("name", Types.VARCHAR),
        new SqlParameter("type", Types.OTHER) // 声明type列的类型为OTHER
    );

SqlParameterSource parameters = new MapSqlParameterSource(testRecord);
Number testId = insertTest.executeAndReturnKey(parameters);

方案三:改用NamedParameterJdbcTemplate执行原生SQL

直接在SQL里写类型转换语法,这种方式更直观:

String sql = "INSERT INTO test_table (name, type) VALUES (:name, :type::test_type)";
Map<String, Object> params = new HashMap<>();
params.put("name", "whatever");
params.put("type", "planning");

KeyHolder keyHolder = new GeneratedKeyHolder();
namedParameterJdbcTemplate.update(sql, new MapSqlParameterSource(params), keyHolder, new String[]{"id"});
Number testId = keyHolder.getKey();

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 07:20:09