Spring的SimpleJdbcInsert发挥了Simple风格,与SimpleJdbcTemplate同属于Simple体系。该类为向数据库中插入数据提供了一个非常快捷的方式,另外它还提供了一套用于返回插入数据的主键的方法:executeAndReturnKeyHolder、executeAndReturnKey。
查看API的时候可以看到executeAndReturnKey这个方法的返回类型是Number类型,当时我就再想如果主键的类型是String类型呢,比如UUID。后来看到还有一个executeAndReturnKeyHolder方法,返回的是一个KeyHolder对象,可以通过keyHolder#getKeys()获取主键的值,另外还有一个getKeyList()方法用于复合主键的情况,这里先撇开不说。
看完API之后那就可以动手了,代码如下:
-
//
jdbcInsert是SimpleJdbcInsert对象
-
Map<String, Object> data = Maps.newHashMap();
-
data.put("id", "t0001");
-
data.put("name", "Tom");
-
data.put("age", 24);
-
KeyHolder keyHolder = jdbcInsert.withTableName("t_tablename")
-
.usingColumns("id", "name", "age")
-
.usingGeneratedKeyColumns("id")
-
.executeAndReturnKeyHolder(data);
-
// 下面主要是对keyHoder进行分析
-
if(keyHolder == null) {
-
return null;
-
}
-
Map<String, Object> keys = keyHolder.getKeys();
-
if(keys == null || keys.size() == 0 || keys.values().size() == 0) {
-
return null;
-
}
-
Object key = keys.values().toArray()[0];
-
if(key == null || !(key instanceof Serializable)) {
-
return null;
-
}
-
if(key instanceof Number) {
-
Long k = (Long)key;
-
return (idType == int.class || idType == Integer.class) ?
-
k.intValue() : k;
-
} else if(key instanceof String) {
-
return (String)key;
-
} else {
-
return (Serializable)key;
-
} // end of if(key instanceof
Number)
如果主键id的类型是int或long上面的代码没有任何问题,但是如果是自定义的UUID等String类型则问题出现了,提示下面的错误:
org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback; uncategorized SQLException for SQL []; SQL state
[HY000]; error code [1364]; Field ‘id’ doesn’t have a default value; nested
exception is java.sql.SQLException: Field ‘id’ doesn’t have a default value
有些奇怪了吧?明明id的值已经传入了,但是错误的提示应该是没有传入id的值。进入到Spring的源代码中,发现代码里面有一些debug信息,于是在log4j中将debug打开:
- log4j.logger.org.springframework.jdbc.core=debug
从打印出来的信息中看,Spring自动生成的Insert语句中竟然没有id字段!!!继续最终源代码,先在org.springframework.jdbc.core.simple.AbstractJdbcInsert类中找到protected
void compileInternal()方法,在代码前加上一个debug信息:
-
protected void compileInternal() {
-
logger.debug("getGeneratedKeyNames:
" +
getColumnNames());
-
tableMetaDataContext.processMetaData(getJdbcTemplate().getDataSource(), getColumnNames(), getGeneratedKeyNames());
-
...
- }
这个时候打印的列表中有id字段,继续最终,最后终于在TableMetaDataContext#createInsertString(java.lang.String[])方法里面找到,关键的代码片段如下:
-
for (String columnName : this.getTableColumns()) {
-
//
这里将SimpleJdbcInsert#usingGeneratedKeyColumns方法中所设置的字段去除了
-
if (!keys.contains(columnName.toUpperCase())) {
-
columnCount++;
-
if (columnCount > 1) {
-
insertStatement.append(", ");
-
}
-
insertStatement.append(columnName);
-
}
-
}
看到这里,我也猛然恍然大悟了。既然在INSERT
INTO语句中设置了UUID的值,那这里就不需要再使用KeyHolder进行返回了,直接获取就是了。这也是为什么KeyHolder中的getKey()方法的返回类型是Number的原因了,因为通常来说需要Spring返回的就是插入数据库中的自增类型的主键值。
分享到:
相关推荐
只提供代码,自己去下载相关jar包谢谢只提供代码,自己去下载相关jar包谢谢只提供代码,自己去下载相关jar包谢谢只提供代码,自己去下载相关jar包谢谢只提供代码,自己去下载相关jar包谢谢
主要介绍了Python3 操作 MySQL 插入一条数据并返回主键 id的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
按照mp的官网介绍,使用mp的insert方法,对于自增的数据库表,mp会把主键写入回实例的对应属性。但实际操作起来,却没有主键。 entity 类设置如下: @TableName(value = "USERINFO") public class UserInfo { /**...
一、创建序列 1.1、直接在PLSQL中设置 1.2、命令创建 create sequence seq_users ##创建序列seq_users increment by 1 ## 步长,每次加1 start with 1 ##从1开始 minvalue 1 ##最小值 maxvalue 9999999 ##最大值 ...
Spring的JdbcTemplate插入操作返回主键ID的方法 - - ITeye技术网站
jdbc保存对象返回一个主键
主要介绍了MyBatis在insert插入操作时返回主键ID的配置的相关资料,需要的朋友可以参考下
主要介绍了Mybatis批量插入数据返回主键的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
使用ODI处理没有主键的表全攻略.docx
在设计主键的时候往往需要考虑以下几点: 1.无意义性:此处无意义是从用户的角度来定义的。这种无意义在一定程度上也会减少数据库的信息冗余。常常有人称呼主键为内部标识,为什么会这样称呼,原因之一在于“内部”...
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数。这篇文章主要介绍了MyBatis中insert操作返回主键的方法,需要的朋友可以参考下
该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主键类中的字段)保存该联合主键类的一个引用,并生成set和get方法,并将该引用注解为@Id ...
Hibernate一对多使用非主键关联设置,参看详细说明
创建一个监控表,一个被调用的存储过程即可,推荐有存储过程编广泛使用的程序使用 调用方法 DECLARE @PKID CHAR(12)='' EXEC [dbo].[SysGetObjectPKId] @ObjectName = '你的表名称',@PKID = @PKID OUTPUT insert 你的...
表中只允许使用一个主键。主键不接受任何重复值和空值。表中的主键值很少更改,因此在选择主键是需要小心,要选择很少发生更改的地方。一个表的主键可以被另一个表的外键引用。 为了更好地理解主键,我们创建一个名...
主要介绍了 Mybatis返回插入主键id的方法,在文章底部给大家补充了Mybatis中insert中返回主键ID的方法,非常不错,需要的朋友可以参考下
SQL判断表是否有主键,如何添加主键和移除主键 这是一个很好的例子个大家分享,以后我会及时更新
ORACLE自增主键设置方法ORACLE自增主键设置方法