使用JdbcTemplate插入记录并获取生成ID时出错,其他操作正常
解决JdbcTemplate插入记录并获取生成ID失败的问题
我完全懂你现在的困扰——JdbcTemplate跑普通的查、改、删都顺得很,唯独插入完想拿数据库自动生成的主键ID就翻车。看你贴的代码片段,问题出在你用的是普通的update()方法,它只返回受影响的行数,根本不会帮你捕获生成的主键。
要搞定这个需求,得用JdbcTemplate专门为获取生成主键设计的重载方法:update(PreparedStatementCreator psc, KeyHolder keyHolder)。下面给你一步步讲怎么改:
核心思路
通过PreparedStatementCreator创建声明要返回生成主键的SQL语句,再用KeyHolder(通常用GeneratedKeyHolder实现类)来接收数据库返回的主键值。
修正后的完整代码
public class DBService { @Autowired private final JdbcTemplate jdbc; private static final Logger logger = LoggerFactory.getLogger(DBService.class); public int addJob(Job modal) { String query = "INSERT INTO JOBS (USERNAME, CREATEDON, STATUS, TYPE, DATA) " + "VALUES (?, ?, ?, ?, ?)"; // 创建KeyHolder实例用来存生成的主键 KeyHolder keyHolder = new GeneratedKeyHolder(); try { // 调用带KeyHolder的update重载方法 jdbc.update(connection -> { // 关键:创建PreparedStatement时指定Statement.RETURN_GENERATED_KEYS PreparedStatement ps = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); // 按顺序设置SQL参数 ps.setString(1, modal.getUsername()); ps.setTimestamp(2, modal.getCreatedOn()); ps.setString(3, modal.getStatus()); ps.setString(4, modal.getType()); ps.setString(5, modal.getData()); return ps; }, keyHolder); // 从KeyHolder中取出生成的主键(这里假设主键是int类型,long的话用longValue()) Integer generatedId = keyHolder.getKey().intValue(); logger.trace("Job插入成功,生成的ID为: {}", generatedId); return generatedId; } catch (Exception e) { logger.error("插入Job记录失败", e); throw new RuntimeException("插入Job时发生错误", e); } } }
几个要注意的点
- 确认你的
JOBS表主键是自增类型:比如MySQL的AUTO_INCREMENT、PostgreSQL的SERIAL/GENERATED AS IDENTITY,不然数据库不会生成主键,自然拿不到。 - 如果是复合主键,别用
getKey(),改用getKeys()方法获取所有生成的键值对。 - 主流数据库(MySQL、PostgreSQL、SQL Server)都支持
Statement.RETURN_GENERATED_KEYS这个JDBC标准,不用额外改SQL语法。
你之前的代码应该是没用到这个带KeyHolder的重载方法,所以才拿不到生成的ID,按上面的代码改完应该就能正常获取了。
内容的提问来源于stack exchange,提问作者Gaurav
相关产品推荐
相关产品推荐

