Mybatis Plus主鍵策略踩坑-ID_WORKER無法自動生成主鍵值
Mybatis Plus 版本 3.2.0
Mybatis Plus的主鍵策略
Mybatis Plus的主鍵策略有如下幾種:
- AUTO 數據庫ID自增
使用AUTO策略時,數據庫建表時需要將主鍵設置成AUTO_INCREMENT
,否則會插入不了 - INPUT 用戶輸入ID
用戶輸入ID - ID_WORKER 全局唯一ID,Long類型的主鍵
全局唯一ID,Long類型的主鍵 - ID_WORKER_STR 字符串全局唯一ID
字符串全局唯一ID - UUID 全局唯一ID,UUID類型的主鍵
UUID類型的主鍵 - NONE 該類型爲未設置主鍵類型
該類型爲未設置主鍵類型
問題描述
這裏以AUTO主鍵策略來演示遇到的問題
- 實體類Student
@TableName("tb_student")
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
@TableId(value = "student_id", type = IdType.ID_WORKER)
private long studentId;
@TableId(value = "student_age")
private int studentAge;
@TableId(value = "student_name")
private String studentName;
@TableId(value = "student_sex")
private int studentSex;
//getter and setter
}
- Mapper等省略
- 測試程序如下:
@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class StudentMapperTest {
@Autowired
StudentMapper studentMapper;
@Test
public void testInsert(){
Student student = new Student();
student.setStudentAge(20);
//1表示男,2表示女
student.setStudentSex(1);
student.setStudentName("憤怒的小猿");
studentMapper.insert(student);
}
}
運行測試代碼,第一次插入進了數據庫,在運行一次,發現數據插入到了數據庫,在運行一次發現報錯了,日誌如下:
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'PRIMARY'
; Duplicate entry '0' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'PRIMARY'
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:242)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:74)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
at com.sun.proxy.$Proxy87.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:271)
意思是說主鍵重複了,我們這裏的策略使用的是ID_WORKER,應該會自動生成纔對,爲什麼沒有自動生成主鍵呢?
問題分析
Mybatis Plus的主鍵值是通過IdWorker這個類生成的,通過對代碼的跟蹤,到MybatisDefaultParameterHandler的如下位置
這裏studentId字段的額值是0,但是在179行判斷的時候使用的是checkValNull()
方法,因爲0!=null
,所以不會進入主鍵值的生成。
那麼問題來了,這個0是哪來的呢。後來再看Student
這個類的時候才發現,studentId的類型是long,long的默認值是0。所以這裏才變成了0.
解決辦法
將用包裝類型Long
來代替long
,替換後再運行測試代碼,發現可以正常插入到數據庫中。ID_WORKER
使用的是雪花算法,所以數據如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-
問題解決。