在Mysql中自己手動(dòng)實(shí)現(xiàn)數(shù)據(jù)列的自增
2023-04-12
很多年前做過(guò)一個(gè)mysql項(xiàng)目,因?yàn)樵趍ysql中沒(méi)有oracle中的sequence序列,所以需要手動(dòng)實(shí)現(xiàn),目的就是解決序號(hào)串行化的問(wèn)題,防止出現(xiàn)重復(fù)序號(hào),因?yàn)闀r(shí)間久遠(yuǎn),原先的代碼找不到了,所以根據(jù)記憶中的思路,結(jié)合現(xiàn)如今的新框架技術(shù)重新總結(jié)一下。
創(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);
// 該方法是在邏輯代碼中調(diào)用的,前提條件是表中已經(jīng)存在該序列
@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語(yǔ)句,此處sql每執(zhí)行一次,current_val都按照自增因子去增加
- @SelectKey需要注意的是,keyProperty中的值需要跟查詢sql中的字段名、Sequence中的數(shù)據(jù)項(xiàng)保持一致,此處設(shè)置是在update執(zhí)行后再執(zhí)行查詢,根據(jù)數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別,這樣就能獲取到更新后的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ù)對(duì)象
Sequence sequence = new Sequence();
// 設(shè)置seq_name
sequence.setSeqName(seqName);
// 執(zhí)行前參數(shù)展示
logger.info("參數(shù)值{}", sequence.toString());
// 執(zhí)行業(yè)務(wù)邏輯
boolean flag = sequenceService.getCurrentVal(sequence);
// 執(zhí)行后參數(shù)展示
logger.info("返回值{}", sequence.toString());
return "T";
}
}
啟動(dòng)測(cè)試
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}
總結(jié)
本文最主要的還是需要掌握selectKey的用法,不管是使用注解還是在映射器中寫(xiě)sql,都需要掌握使用方法。
本文僅代表作者觀點(diǎn),版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請(qǐng)?jiān)谖闹凶⒚鱽?lái)源及作者名字。
免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請(qǐng)及時(shí)與我們聯(lián)系進(jìn)行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com






