SQL Server 2012+中如何通过NamedParameterJdbcTemplate获取序列生成ID
解决SQL Server 2012 Sequence+默认约束下,Spring NamedParameterJdbcTemplate获取生成主键的问题
没问题,这个场景是可以拿到生成的ChangeEventId的,并不是用Sequence就做不到——只是需要调整一下NamedParameterJdbcTemplate.update的调用方式,明确告诉JDBC驱动要捕获哪个列的生成值。
核心原因
SQL Server的IDENTITY自增列会被JDBC驱动自动识别并返回生成值,但你用的是Sequence+默认约束的方式生成主键,这种情况驱动不会自动捕获生成值,必须显式指定要返回的主键列名。
具体实现步骤
编写插入SQL时,主键列使用DEFAULT或省略
因为主键列已经通过默认约束关联了Sequence,所以插入时不需要手动赋值,要么直接省略该列,要么显式写DEFAULT:-- 方式1:省略主键列 INSERT INTO YourTableName (Column1, Column2) VALUES (:col1, :col2); -- 方式2:显式使用DEFAULT INSERT INTO YourTableName (ChangeEventId, Column1, Column2) VALUES (DEFAULT, :col1, :col2);调用update时指定返回的主键列名
使用NamedParameterJdbcTemplate.update的重载方法,传入KeyHolder的同时,指定要返回的主键列名数组:String insertSql = "INSERT INTO ChangeEvents (EventName, EventTime) VALUES (:eventName, :eventTime)"; // 构建参数 SqlParameterSource params = new MapSqlParameterSource() .addValue("eventName", "用户登录事件") .addValue("eventTime", LocalDateTime.now()); // 初始化KeyHolder KeyHolder keyHolder = new GeneratedKeyHolder(); // 关键:最后一个参数指定要返回的主键列名 namedParameterJdbcTemplate.update(insertSql, params, keyHolder, new String[]{"ChangeEventId"}); // 获取生成的主键值(根据你的列类型调整,比如INT用intValue()) Long generatedId = keyHolder.getKey().longValue();
注意事项
- JDBC驱动版本:确保使用的SQL Server JDBC驱动版本不低于6.0,旧版本对Sequence的支持可能存在问题。
- 列类型匹配:
getKey()返回的是Number类型,要根据你主键列的实际类型(比如INT/BIGINT)转换为对应的数值类型。 - 不要手动赋值主键:如果插入时手动给
ChangeEventId赋值,那么KeyHolder拿到的就是你指定的值,而不是Sequence生成的。
内容的提问来源于stack exchange,提问作者ithinkisam
相关产品推荐
相关产品推荐

