Spring Boot中为非@Id的transactionNumber字段生成自增值(MySQL)
为Accounts实体类的transactionNumber实现自动填充(MySQL)
方案一:使用MySQL序列(MySQL 8.0+适用)
MySQL 8.0及以上版本支持原生序列,可以直接通过序列生成transactionNumber的自增值:
- 先在MySQL中创建专属序列:
CREATE SEQUENCE transaction_number_seq START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 999999999 CYCLE;
- 修改Accounts实体类,为
transactionNumber配置序列生成规则:
@Entity @SequenceGenerator(name = "account_seq", initialValue = 1, allocationSize = 1) @SequenceGenerator(name = "transaction_seq", sequenceName = "transaction_number_seq", allocationSize = 1) public class Accounts { @Id @GeneratedValue(generator = "account_seq") private Integer accountNumber; @GeneratedValue(generator = "transaction_seq", strategy = GenerationType.SEQUENCE) private int transactionNumber; // 其余字段、getter/setter保持不变 }
注:将原主键序列的生成器名称改为account_seq,避免与新序列生成器冲突。
方案二:使用数据库触发器(兼容所有MySQL版本)
如果你的MySQL版本低于8.0,不支持原生序列,可通过触发器实现自动填充:
- 创建一个用于维护
transactionNumber自增计数的辅助表:
CREATE TABLE transaction_counter ( id INT PRIMARY KEY AUTO_INCREMENT, current_value INT NOT NULL DEFAULT 1 ); INSERT INTO transaction_counter (current_value) VALUES (1);
- 编写插入触发器,在新增Accounts记录时自动生成
transactionNumber:
DELIMITER // CREATE TRIGGER before_insert_accounts BEFORE INSERT ON Accounts FOR EACH ROW BEGIN UPDATE transaction_counter SET current_value = current_value + 1; SELECT current_value INTO NEW.transactionNumber FROM transaction_counter; END // DELIMITER ;
- 实体类无需额外注解,保持
transactionNumber字段原样即可,插入时触发器会自动赋值。
方案三:使用JPA的@PrePersist注解(代码层面控制)
通过JPA的生命周期注解,在实体保存前生成transactionNumber的值:
- 修改Accounts实体类,添加
@PrePersist方法:
@Entity @SequenceGenerator(name = "seq", initialValue = 1, allocationSize = 1) public class Accounts { @Id @GeneratedValue(generator = "seq") private Integer accountNumber; private int transactionNumber; // 注入AccountsRepository(需确保Spring环境中已配置) @Autowired private AccountsRepository accountsRepository; // 其余字段... @PrePersist public void generateTransactionNumber() { Integer maxTxnNum = accountsRepository.findMaxTransactionNumber(); this.transactionNumber = (maxTxnNum == null) ? 1 : maxTxnNum + 1; } // getter/setter... }
- 在AccountsRepository中添加查询最大值的方法:
public interface AccountsRepository extends JpaRepository<Accounts, Integer> { @Query("SELECT MAX(a.transactionNumber) FROM Accounts a") Integer findMaxTransactionNumber(); }
注:高并发场景下需添加事务控制(如@Transactional(propagation = Propagation.REQUIRES_NEW)),避免出现重复值。
内容的提问来源于stack exchange,提问作者Sai Chakra
相关产品推荐
相关产品推荐

