User.java
Springboot/bookstore-api/src/main/java/com/example/bookstore/entity/User.java
package com.example.bookstore.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.time.LocalDateTime;
/**
* 使用者 Entity(實體類別)——對應資料庫中的 users 資料表。
*
* 【JPA / Hibernate 核心觀念:ORM 物件關聯對映】
* Entity 是「Java 物件」與「資料庫資料列」之間的橋樑。
* Hibernate 會根據這個類別上的註解:
* 1. 自動建立 / 更新資料表結構(依 application.yml 的 ddl-auto 設定)
* 2. 查詢時,把結果集的每一列轉成一個 User 物件
* 3. 儲存時,把 User 物件的內容轉成 INSERT / UPDATE 語句
*/
@Entity // 宣告這是一個 JPA Entity,交由 Hibernate 管理
@Table(
name = "users", // 指定資料表名稱。若不指定則預設用類別名稱 user,
// 但 user 是 MySQL 的保留字,容易出錯,因此改名為 users
uniqueConstraints = {
// 資料庫層級的「唯一性約束」:確保帳號與 Email 不重複
@UniqueConstraint(name = "uk_users_username", columnNames = "username"),
@UniqueConstraint(name = "uk_users_email", columnNames = "email")
}
)
public class User {
/** 主鍵(Primary Key) */
@Id
// IDENTITY 策略:主鍵交給 MySQL 的 AUTO_INCREMENT 自動產生流水號
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/** 登入帳號:NOT NULL、最長 50 字元 */
@Column(nullable = false, length = 50)
private String username;
/**
* 密碼:儲存的是 BCrypt「雜湊值」,絕對不能存明碼!
* BCrypt 雜湊字串長度約 60 字元,欄位保留 100 字元較保險。
*/
@Column(nullable = false, length = 100)
private String password;
/** 電子信箱 */
@Column(nullable = false, length = 100)
private String email;
/**
* 角色:使用列舉(enum)型別。
*
* EnumType.STRING → 資料庫實際儲存 "ROLE_USER" 這樣的「文字」。
* 若用預設的 EnumType.ORDINAL 會儲存 0、1 這種「順序數字」,
* 一旦日後調整 enum 的宣告順序,舊資料的意義就全部錯亂,
* 因此實務上幾乎一律使用 STRING。
*/
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 20)
private Role role;
/**
* 建立時間。
* updatable = false → 之後執行 UPDATE 時,Hibernate 不會更動這個欄位。
*/
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
/**
* 【JPA 規定】Entity 一定要有「無參數建構子」。
* Hibernate 從資料庫讀取資料時,會先用它建立空物件,再逐一填入欄位值。
*/
public User() {
}
/** 方便在程式中建立新使用者的建構子 */
public User(String username, String password, String email, Role role) {
this.username = username;
this.password = password;
this.email = email;
this.role = role;
}
/**
* 【生命週期回呼 Lifecycle Callback】
* @PrePersist:在 Hibernate 執行 INSERT「之前」自動被呼叫,
* 這裡用來自動填入建立時間,不需要每次手動設定。
*/
@PrePersist
protected void onCreate() {
this.createdAt = LocalDateTime.now();
}
// ========================= Getter / Setter =========================
// Hibernate 與 Jackson(JSON 轉換)都是透過 getter/setter 存取欄位。
// 實務上許多團隊會用 Lombok 的 @Getter / @Setter 省去這些樣板程式碼;
// 教學專案為了完整呈現原貌,選擇手動撰寫。
public Long getId() {
return id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
}
Artigos relacionados
BookstoreApiApplication.java
BookstoreApiApplication.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/BookstoreApiApplication.java).
Ler artigo →DataInitializer.java
DataInitializer.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/DataInitializer.java).
Ler artigo →SecurityConfig.java
SecurityConfig.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/SecurityConfig.java).
Ler artigo →AuthController.java
AuthController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/AuthController.java).
Ler artigo →BookController.java
BookController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/BookController.java).
Ler artigo →ApiErrorResponse.java
ApiErrorResponse.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/dto/ApiErrorResponse.java).
Ler artigo →