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

Spring 入門實戰:JPA 核心概念、實體映射與關聯關係完整指南

     編輯:Java 綜合教學

Spring 入門實戰:JPA 核心概念、實體映射與關聯關係完整指南

使用 Spring 一段時間後,決定深入學習 JPA(Java Persistence API)。本文記錄從 ORM 基礎概念到 JPA 實體定義、屬性映射、四大關聯關係、單向/雙向導航的完整學習筆記,並附上可直接運行的程式碼範例。

ORM 基礎概念

ORM (Object/Relational Mapping) 解決物件導向模型與關係型資料庫範式不匹配的問題。透過元數據描述映射關係,將物件自動持久化到資料庫,本質是資料形式轉換。雖引入額外開銷,但極大提升開發效率與可維護性。

主流 ORM 框架具備四大核心功能:映射元數據、CRUD API、物件查詢語言(JPQL/HQL)、物件圖導航獲取資料。

JPA 核心優勢

  • 標準化 ORM 功能與 API,降低對特定實作(Hibernate/EclipseLink)的耦合。
  • 提供 EntityManager 統一管理實體生命週期。
  • 支援 JPQL 面向物件查詢,減少原生 SQL 硬編碼。
  • 透過 persistence.xml 或 Spring Data JPA 自動配置,零侵入式整合。

實體定義與基礎映射

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;  // 欄位名同屬性名,無需 @Column

    @Column(name = "passwd")  // 資料庫欄位名不同,需指定
    private String password;

    @Transient  // 不映射到資料庫
    private String others;
}

關鍵註解:

  • @Entity:標記為持久化實體,對應一張表。
  • @Table:指定表名、Schema、唯一約束等。
  • @Id + @GeneratedValue:主鍵生成策略(IDENTITY/SEQUENCE/AUTO/TABLE)。
  • @Column:自訂欄位名、長度、可空、唯一等。
  • @Transient:忽略該屬性,不持久化。

四大關聯關係映射

類型註解外鍵位置典型場景
一對一@OneToOne + @JoinColumn任一端(通常主表)用戶-身份證、訂單-付款
多對一@ManyToOne + @JoinColumn多方(員工表)員工-公司、訂單-用戶
一對多@OneToMany + @JoinColumn 或 mappedBy多方(書籍表)學生-書籍、部門-員工
多對多@ManyToMany + @JoinTable中間表學生-課程、產品-目錄

程式碼範例:多對多(產品-目錄)

@Entity
public class Product {
    @Id @GeneratedValue private Long id;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "product_catalog",
        joinColumns = @JoinColumn(name = "product_id"),
        inverseJoinColumns = @JoinColumn(name = "catalog_id"))
    private Set catalogs = new HashSet<>();
}

@Entity
public class Catalog {
    @Id @GeneratedValue private Long id;
    // 雙向導航可在這裡加 @ManyToMany(mappedBy = "catalogs")
}

中間表 product_catalog 包含兩外鍵組成聯合主鍵,JPA 自動維護。

關聯導航方向性

  • 單向: 僅源端持有目標端引用(如 User → Address)。
  • 雙向: 兩端互持引用,需在「被動端」用 mappedBy 指向「主動端」屬性名,由主動端維護外鍵,被動端僅作鏡像查詢,不影響資料庫結構。
// 主動端
@OneToOne
@JoinColumn(name = "address_id")
private Address address;

// 被動端(雙向)
@OneToOne(mappedBy = "address")
private User user;

最佳實踐提醒

  1. 預設採用 LAZY 載入(@OneToMany/@ManyToMany 預設即為 LAZY),避免 N+1 問題配合 EntityGraph 或 JOIN FETCH 精確載入。
  2. 雙向關聯務必同步兩端集合(新增/移除時雙邊操作),建議在實體內封裝 addXxx/removeXxx 方法。
  3. cascade 謹慎使用,REMOVE 可能誤刪關聯端資料,優先手動控制。
  4. 實體類必須有無參構造器,非 final、非 static 欄位,實作 equals/hashCode 基於業務主鍵(非資料庫 ID)。

下一步

後續將介紹 JPA 配置(persistence.xml/Spring Data JPA)、Repository 使用、JPQL/QueryDSL 查詢、事務管理與效能調優。

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