为啥 Spring 的 JDBC 模板不使用表默认值
Posted
技术标签:
【中文标题】为啥 Spring 的 JDBC 模板不使用表默认值【英文标题】:Why does Spring's JDBC Templates doesn't use the tables default value为什么 Spring 的 JDBC 模板不使用表默认值 【发布时间】:2013-12-28 04:15:31 【问题描述】:我在 mysql 中有一个表,我正在使用 JDBC 模板向该表中执行插入操作。
其中一列有一个默认值,我没有在Map<String, Object> parameters
映射中指定它。
我收到了一个异常Column 'colName' cannot be null
。
谁能解释一下?
谢谢
*编辑:代码*
contactDetailsInsertTemplate = new SimpleJdbcInsert( dataSource ).withTableName("contactdetails").usingGeneratedKeyColumns("contactcode"); Map<String, Object> parameters = new HashMap<String, Object>(); Number newId = contactDetailsInsertTemplate.executeAndReturnKey(parameters);
【问题讨论】:
请出示您正在使用的代码。 【参考方案1】:您需要限制在 SQL 插入中指定的列。
见SimpleJdbcInsert.usingColumns()
如果不这样做,SQL 语句将需要所有列的值,并且不能使用默认值。
例如使用
insert into mytable (col1, col2) values (val1, val2);
而不是
insert into mytable values (val1, val2);
【讨论】:
【参考方案2】:问题出在其他地方:当我使用SimpleJdbcInsert
并将参数映射传递给它时,我只是希望仅使用我提供的参数来创建插入语句。我在表中有一个带有 DEFAULT 值的 NOT NULL 列,我不想指定它。我也不想明确地将所有列名放在usingColumns()
中,因为我只是在创建参数映射时这样做了!我为什么要再做一次?问题是SimpleJdbcInsert
想要更聪明,并将所有列添加到不需要的插入语句中。为什么不只使用参数映射提供的列来创建语句?
见:http://forum.spring.io/forum/spring-projects/data/54209-simplejdbcinsert-and-columns-with-default-values
【讨论】:
【参考方案3】:INSERT INTO mytable (1,null)
与 INSERT INTO mytable (1)
不同。先验专门插入null
,后者将决定权留给数据库(这将是默认值)。 Spring JDBC 做的是前者。
【讨论】:
感谢您的回答。您的两个答案都是正确的,但 NickJ 的答案对于特定问题更准确。我希望我能接受你们两个,但我会接受他并支持你:)。【参考方案4】:您可以将具有默认值的列作为参数添加到usingGeneratedKeyColumns()
。
作为该方法的参数包含的列名将从生成的INSERT
语句中省略。
【讨论】:
【参考方案5】:由于 OP 正在向 SimpleJdbcInsert
提供 MAP。
这就是我所做的。
我确保 MAP 仅包含我想要插入的列。
我提取了 Map 键并将它们转换为String[]
,如下所示
Set<String> set = map.keySet();
String[] columnNames = (String[]) map.keySet().toArray(new String[set.size()]);`
在启动SimpleJdbcInsert
时,我传入了我想要使用的列,如下所示
SimpleJdbcInsert sji = new SimpleJdbcInsert(dataSource).withTableName("table_name");
sji.usingColumns(columnNames);`
希望对你有帮助。
【讨论】:
以上是关于为啥 Spring 的 JDBC 模板不使用表默认值的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot jdbc模板在自定义模式下的postgres中找不到表