1. 引言

本文将快速探讨在Spring JDBC开发中,如何获取插入实体后数据库自动生成的主键值。

2. Maven依赖

首先需要在pom.xml中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

最新版本可在Maven Central查看:

3. 获取自增主键

3.1 场景定义

创建sys_message表,包含两列:id(自增主键)和message

CREATE TABLE IF NOT EXISTS sys_message (
    id bigint(20) NOT NULL AUTO_INCREMENT,
    message varchar(100) NOT NULL,
    PRIMARY KEY (id)
);

3.2 使用JdbcTemplate

通过JdbcTemplate实现插入记录并返回自增id

String INSERT_MESSAGE_SQL 
  = "insert into sys_message (message) values(?) ";
    
public long insertMessage(String message) {    
    KeyHolder keyHolder = new GeneratedKeyHolder();

    jdbcTemplate.update(connection -> {
        PreparedStatement ps = connection
          .prepareStatement(INSERT_MESSAGE_SQL, Statement.RETURN_GENERATED_KEYS);
          ps.setString(1, message);
          return ps;
        }, keyHolder);

        return (long) keyHolder.getKey();
    }
}

⚠️ 关键点keyHolder对象会保存update()方法返回的自增主键,通过getKey()获取。

验证方法:

@Test
public void 
  insertJDBC_whenLoadMessageByKey_thenGetTheSameMessage() {
    long key = messageRepositoryJDBCTemplate.insert(MESSAGE_CONTENT);
    String loadedMessage = messageRepositoryJDBCTemplate
      .getMessageById(key);

    assertEquals(MESSAGE_CONTENT, loadedMessage);
}

3.3 使用SimpleJdbcInsert

另一种实现方式是使用SimpleJdbcInsert

@Repository
public class MessageRepositorySimpleJDBCInsert {

    SimpleJdbcInsert simpleJdbcInsert;

    @Autowired
    public MessageRepositorySimpleJDBCInsert(DataSource dataSource) {
        simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
          .withTableName("sys_message").usingGeneratedKeyColumns("id");
    }
    
    //...
}

调用executeAndReturnKey方法插入记录并返回主键:

public long insert(String message) {
    Map<String, Object> parameters = new HashMap<>(1);
    parameters.put("message", message);
    Number newId = simpleJdbcInsert.executeAndReturnKey(parameters);
    return (long) newId;
}

验证方法:

@Test
public void 
  insertSimpleInsert_whenLoadMessageKey_thenGetTheSameMessage() {
    long key = messageRepositorySimpleJDBCInsert.insert(MESSAGE_CONTENT);
    String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key);

    assertEquals(MESSAGE_CONTENT, loadedMessage);
}

4. 总结

我们探讨了两种在Spring JDBC中插入记录并获取自增主键的方法:

  • JdbcTemplate:适用于复杂SQL场景,需手动处理PreparedStatement
  • SimpleJdbcInsert:简单粗暴的API,适合标准插入操作

完整代码示例见GitHub仓库


原始标题:Obtaining Auto-generated Keys in Spring JDBC