首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

Hibernate 映射 MySQL 自增主鍵:native 與 assigned 策略差異與實戰配置

     編輯:MySQL 綜合教學

在 Hibernate 中正確映射 MySQL AUTO_INCREMENT 主鍵,關鍵在於選擇適當的識別符產生策略(<generator>)。本文詳細解析 native、assigned、identity 等策略差異,提供完整映射檔案與程式碼範例。

MySQL 資料表定義

CREATE TABLE `anietest`.`user` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(50),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE UNIQUE INDEX `PRIMARY` ON `anietest`.`user`(`id`);

Hibernate 映射檔 (hbm.xml)

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
  <class name="org.nieweiguo.User" table="user" catalog="anietest">
    <id name="id" type="java.lang.Integer">
      <column name="id" />
      <generator class="native" />
    </id>
    <property name="username" type="java.lang.String">
      <column name="username" length="50" />
    </property>
  </class>
</hibernate-mapping>

核心策略差異解析

策略適用資料庫行為Hibernate 版本備註
nativeMySQL, PostgreSQL, Oracle, SQL Server 等自動選擇 identity (MySQL/SQL Server) 或 sequence (Oracle/PostgreSQL)全版本跨資料庫首選,MySQL 下等同 identity
identityMySQL, SQL Server, DB2, Sybase依賴資料庫自增欄位,INSERT 後立即取回生成值全版本不支援批次插入優化
assigned所有由應用程式手動指定 ID 值全版本需在 save() 前設定 id,適用業務主鍵
increment所有Hibernate 記憶體內計數器產生 ID (單進程)全版本叢集/多實例環境禁用,會產生重複 ID
uuid/uuid2所有產生 UUID 字串3.2+分散式系統適用,需 CHAR(36) 儲存

程式碼實戰對比

使用 native (推薦)

// Action / Service 層
UserForm userForm = (UserForm) form;
UserDAO userDao = new UserDAO();
User user = new User();
// user.setId(0); // 不需設定,Hibernate 交由資料庫自增
user.setUsername(userForm.getUsername());
userDao.save(user); // INSERT 後 user.id 自動填入生成值

使用 assigned (手動指定)

<generator class="assigned" />

// 程式碼必須手動設定 ID
User user = new User();
user.setId(0); // 或任何未使用的值,但通常由業務邏輯決定
user.setUsername(userForm.getUsername());
userDao.save(user);
關鍵差異: assigned 要求應用層保證 ID 唯一性,native 則交由資料庫保證。MySQL AUTO_INCREMENT 配合 native 是最簡單、最安全的組合。

JPA / Spring Data JPA 註解寫法

@Entity
@Table(name = "user", catalog = "anietest")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // MySQL 對應 native
    @Column(name = "id")
    private Integer id;

    @Column(name = "username", length = 50)
    private String username;
    // getter/setter
}

GenerationType.IDENTITY 對應 MySQL AUTO_INCREMENT,GenerationType.AUTO 對應 native(由 JPA 提供者決定)。

常見問題與解決

1. save() 後 ID 為 null/0

原因:generator 設錯(如用 increment 但未 flush)、資料表無 AUTO_INCREMENT、交易未提交。
解決:確認映射檔 native、資料表定義正確、session.flush() 或交易提交後取值。

2. 批次插入效能差

identity/native 需逐筆 INSERT 取回 ID,無法使用 JDBC 批次。
解決:大量匯入時暫時改用 assigned + 應用層產生 ID(如雪花算法),或使用 LOAD DATA INFILE 繞過 ORM。

3. 主鍵類型不匹配

資料表 BIGINT 實體用 Integer 會溢位。
解決:實體用 Long 對應 BIGINT,Integer 對應 INT。

總結

MySQL 自增主鍵映射,首選 native (或 JPA IDENTITY),零配置跨資料庫相容、資料庫保證唯一、程式碼最簡潔。僅在業務主鍵、分散式 ID、批次匯入等特殊場景考慮 assigned、uuid 等策略。映射檔與實體類型、資料表定義三者嚴格對齊,是避免主鍵問題的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved