MyBatis-Plus 主鍵生成策略配置與實戰
在數據庫操作中,主鍵的生成方式直接影響數據插入的效率和數據唯一性,MyBatis-Plus 提供了多種內置的主鍵生成策略,能適配不同業務場景的需求,不用手動編寫主鍵生成邏輯,既省心又能避免主鍵衝突問題。
一、默認主鍵策略與註解配置
MyBatis-Plus 默認的主鍵生成策略是 ID_WORKER(雪花算法),但更常用的是通過 @TableId 註解為實體類指定主鍵策略。先看基礎配置方式:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
@Data
public class User {
// 指定主鍵類型為自增(AUTO),適配數據庫自增主鍵
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private Integer age;
private String email;
}
這裏 IdType.AUTO 表示使用數據庫的自增主鍵,需要先在數據庫表中把 id 字段設置為自增(比如 MySQL 中設置 AUTO_INCREMENT),插入數據時無需手動設置 id,MyBatis-Plus 會自動獲取數據庫生成的自增值。
二、常用主鍵策略詳解
MyBatis-Plus 提供了多種 IdType 枚舉值,對應不同的主鍵生成邏輯:
1. IdType.AUTO:數據庫自增
適合單庫單表、主鍵需連續遞增的場景,比如用户表、訂單表等基礎業務表。
// 插入數據時無需設置id,數據庫自動生成
User user = new User();
user.setUsername("test_auto");
user.setAge(25);
userMapper.insert(user);
// 插入後可獲取數據庫生成的id
Long generatedId = user.getId();
2. IdType.ASSIGN_ID:雪花算法生成 ID
雪花算法(Snowflake)會生成 64 位的長整型 ID,包含時間戳、機器標識、序列號等信息,適合分佈式系統,能保證主鍵全局唯一,且趨勢遞增。
@Data
public class Order {
// 雪花算法生成主鍵
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private Long userId;
private String orderNo;
}
// 插入時無需設置id,MyBatis-Plus自動生成雪花ID
Order order = new Order();
order.setUserId(1001L);
order.setOrderNo("ORD20251206");
orderMapper.insert(order);
System.out.println("雪花算法生成的ID:" + order.getId()); // 輸出類似 1765000000000000001 的長整型ID
3. IdType.ASSIGN_UUID:生成 UUID
適合需要字符串類型主鍵的場景,生成 32 位的 UUID 字符串(不帶橫線),全局唯一,無需依賴數據庫。
@Data
public class Product {
// UUID生成字符串主鍵,注意字段類型為String
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private String productName;
private BigDecimal price;
}
// 插入數據,自動生成UUID主鍵
Product product = new Product();
product.setProductName("筆記本電腦");
product.setPrice(new BigDecimal("5999"));
productMapper.insert(product);
System.out.println("UUID主鍵:" + product.getId()); // 輸出類似 5f8a7b9c1d2e3f4a5b6c7d8e9f0a1b2c 的字符串
4. IdType.INPUT:手動輸入主鍵
適合主鍵由業務邏輯生成的場景,比如訂單號作為主鍵、用户編號自定義規則等,插入時必須手動設置主鍵值,否則會報錯。
@Data
public class CustomCode {
// 手動輸入主鍵
@TableId(type = IdType.INPUT)
private String code;
private String name;
}
// 必須手動設置主鍵值
CustomCode customCode = new CustomCode();
customCode.setCode("CODE20251206001"); // 業務自定義主鍵
customCode.setName("測試編碼");
customCodeMapper.insert(customCode);
三、全局主鍵策略配置
如果項目中大部分實體類使用相同的主鍵策略,無需逐個添加 @TableId 註解,可通過全局配置統一設置:
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public GlobalConfig globalConfig() {
GlobalConfig config = new GlobalConfig();
// 設置全局主鍵策略為雪花算法(ASSIGN_ID)
config.getDbConfig().setIdType(IdType.ASSIGN_ID);
return config;
}
// 分頁插件(非主鍵配置,僅為配置類完整性展示)
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
配置後,實體類若未單獨指定 @TableId,則默認使用雪花算法生成主鍵,既統一了規範,又減少了重複註解的編寫。
四、注意事項
-
使用 IdType.AUTO 時,必須確保數據庫表的主鍵字段已開啓自增,否則插入會報錯;
-
雪花算法(ASSIGN_ID)依賴機器時鐘,若時鐘回撥可能導致主鍵衝突,生產環境需保證服務器時鐘同步;
-
ASSIGN_UUID 生成的主鍵是字符串類型,實體類主鍵字段需定義為 String,否則會出現類型轉換異常;
-
全局配置和實體類註解同時存在時,實體類註解優先級更高,可靈活適配個別表的特殊需求。
合理選擇主鍵生成策略,能讓數據插入更高效、更安全。比如分佈式系統優先選雪花算法,單庫單表追求主鍵連續選自增,自定義業務編碼選手動輸入,MyBatis-Plus 的主鍵策略配置能精準匹配不同業務場景的需求,讓主鍵管理變得簡單可控。