SQL插入人员时基于上条记录自增ID的实现方式及配置位置咨询
首先明确结论:不要在getter方法中实现该逻辑
实体类的getter/setter仅用于属性的读写操作,和持久化、id生成逻辑耦合会破坏单一职责原则,后续实体类被其他场景复用时极易触发非预期的逻辑,排查问题成本极高。
推荐实现方案(生产环境标准用法)
直接使用数据库自带的自增主键特性即可,不需要手动编写id计算逻辑,天然规避并发重复、手动计算错误的问题。
配置步骤:
- 修改数据库
people表的id字段为自增主键,以MySQL为例:
ALTER TABLE people MODIFY COLUMN id INT AUTO_INCREMENT PRIMARY KEY;
- 调整DAO层插入逻辑,插入时不需要传id,插入完成后将数据库生成的id回写到Person对象即可:
import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; import java.sql.PreparedStatement; import java.sql.Statement; public Person addPerson(Person person) { // 插入语句去掉id字段,由数据库自动生成 String sql = "INSERT INTO people (name) values (?);"; KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(connection -> { PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); // 注:你原有Person类中name属性定义为int是错误的,需改为String类型 ps.setString(1, person.getName()); return ps; }, keyHolder); // 将生成的id回写到person对象 person.setId(keyHolder.getKey().intValue()); return person; }
手动实现id生成的方案(仅特殊场景使用)
如果因业务限制不能使用数据库自增主键,可将id生成逻辑写在DAO层的addPerson方法中,代码如下:
public Person addPerson(Person person) { // 查当前最大id,无数据时返回0,加1即为新id Integer maxId = jdbcTemplate.queryForObject("SELECT COALESCE(MAX(id), 0) FROM people", Integer.class); int newId = maxId + 1; person.setId(newId); String sql = "INSERT INTO people (id, name) values (?, ?);"; jdbcTemplate.update(sql, person.getId(), person.getName()); return person; }
注意:该方案存在并发风险,多线程同时插入时可能出现id重复导致插入失败,生产环境使用需要额外加锁、调整事务隔离级别做兼容,优先推荐自增主键方案。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

