You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:20:37