如何使用SimpleJdbcInsert插入含枚举类型列的数据?
解决PostgreSQL自定义枚举类型插入失败问题
问题原因
JDBC默认会把字符串参数识别为varchar类型,而PostgreSQL不会自动将varchar转换为自定义枚举类型test_type,因此抛出类型不匹配错误。你之前尝试在字符串后加::test_type无效,是因为JDBC把整个字符串当成了字段值,而非SQL语法里的类型转换逻辑。
可行解决方案
方案一:用Java枚举对应数据库枚举(推荐,类型安全)
- 先定义和数据库
test_type完全匹配的Java枚举(注意大小写要和数据库枚举值一致,PostgreSQL枚举大小写敏感):
public enum TestType { planning // 其他枚举值按需添加 }
- 修改插入代码,传入枚举实例并指定参数类型:
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
相关产品推荐
相关产品推荐

