在Mysql中自己手動實現(xiàn)數(shù)據列的自增
2023-04-12
很多年前做過一個mysql項目,因為在mysql中沒有oracle中的sequence序列,所以需要手動實現(xiàn),目的就是解決序號串行化的問題,防止出現(xiàn)重復序號,因為時間久遠,原先的代碼找不到了,所以根據記憶中的思路,結合現(xiàn)如今的新框架技術重新總結一下。
創(chuàng)建表
創(chuàng)建sequence表,seq_name在表中是唯一的。
CREATE TABLE `test`.`sequence` (
`seq_name` VARCHAR(100) NOT NULL,
`current_val` INT NOT NULL,
`increment_val` INT NOT NULL DEFAULT 1);
seq_name |
current_val |
increment_val |
role_sn |
1 |
1 |
user_sn |
1 |
1 |
dept_sn |
1 |
1 |
創(chuàng)建Mapper
@Repository
public interface SequenceMapper {
// 該方法主要是初始化
@Insert("INSERT INTO sequence (seq_name, current_val, increment_val) VALUES(#{seqName}, #{currentVal}, #{currentVal})")
public void insert(Sequence sequence);
// 該方法是在邏輯代碼中調用的,前提條件是表中已經存在該序列
@Update("UPDATE sequence SET current_val = current_val + increment_val WHERE seq_name = #{seqName}")
@SelectKey(statement = "SELECT current_val AS currentVal, increment_val AS incrementVal FROM sequence WHERE seq_name = #{seqName}", before = false, resultType = Sequence.class, keyProperty = "currentVal,incrementVal")
public boolean updateCurrentVal(Sequence sequence);
}
- @Update就是我們需要執(zhí)行的sql語句,此處sql每執(zhí)行一次,current_val都按照自增因子去增加
- @SelectKey需要注意的是,keyProperty中的值需要跟查詢sql中的字段名、Sequence中的數(shù)據項保持一致,此處設置是在update執(zhí)行后再執(zhí)行查詢,根據數(shù)據庫的默認隔離級別,這樣就能獲取到更新后的current_val值
創(chuàng)建Service
@Service
public class SequenceService {
protected final static Logger logger = LoggerFactory.getLogger(SequenceService.class);
@Autowired
public SequenceMapper sequenceMapper;
public void insert(Sequence sequence) {
sequenceMapper.insert(sequence);
}
public boolean getCurrentVal(Sequence sequence){
return sequenceMapper.updateCurrentVal(sequence);
}
}
Controller代碼
@RestController
public class MybatisController {
protected final static Logger logger = LoggerFactory.getLogger(MybatisController.class);
@GetMapping("mybatis/getCurrentVal")
public String getCurrentVal(String seqName) {
// 定義參數(shù)對象
Sequence sequence = new Sequence();
// 設置seq_name
sequence.setSeqName(seqName);
// 執(zhí)行前參數(shù)展示
logger.info("參數(shù)值{}", sequence.toString());
// 執(zhí)行業(yè)務邏輯
boolean flag = sequenceService.getCurrentVal(sequence);
// 執(zhí)行后參數(shù)展示
logger.info("返回值{}", sequence.toString());
return "T";
}
}
啟動測試
http://127.0.0.1:8080/mybatis/getCurrentVal?seqName=role_sn
2022-06-22 17:52:02.480 INFO 10004 --- [nio-8080-exec-1] com.example.web.MybatisController : 參數(shù)值Sequence{seqName='role_sn', currentVal=null, incrementVal=null}
2022-06-22 17:52:02.506 INFO 10004 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-06-22 17:52:04.287 INFO 10004 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-06-22 17:52:04.360 INFO 10004 --- [nio-8080-exec-1] com.example.web.MybatisController : 返回值Sequence{seqName='role_sn', currentVal=2, incrementVal=1}
總結
本文最主要的還是需要掌握selectKey的用法,不管是使用注解還是在映射器中寫sql,都需要掌握使用方法。
本文僅代表作者觀點,版權歸原創(chuàng)者所有,如需轉載請在文中注明來源及作者名字。
免責聲明:本文系轉載編輯文章,僅作分享之用。如分享內容、圖片侵犯到您的版權或非授權發(fā)布,請及時與我們聯(lián)系進行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com





