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

EJB 3.0 開發指南:組合主鍵實戰與最佳實踐

     編輯:Java 相關知識

主鍵類型演進

前例皆使用單一 @Id(generate=GeneratorType.AUTO) 自動生成主鍵。實務上主鍵可為:

  • Java 基本型別或包裝類別 (Integer, String 等)
  • 組合主鍵類別(含多欄位/屬性)

使用組合主鍵時,必須將生成策略設為 GeneratorType.NONE,由程式指派主鍵值。主鍵類別必須實作 hashCode() 與 equals()。

完整實戰範例:學生資料管理

1. 組合主鍵類別 Name.java

@DependentObject(access = AccessType.PROPERTY)
public class Name implements Serializable {
    private String first, last;
    // 建構子、getter/setter 略

    public int hashCode() { return (first + last).hashCode(); }
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Name)) return false;
        Name n = (Name) o;
        return first.equals(n.first) && last.equals(n.last);
    }
}

2. 實體 Bean Student.java

@Entity @Table(name="STUDENT")
public class Student implements Serializable {
    private Name name;
    private String grade, email;

    @Id(generate = GeneratorType.NONE)
    @Dependent(
        @DependentAttribute(name="first", column=@Column(name="FIRST")),
        @DependentAttribute(name="last",  column=@Column(name="LAST"))
    )
    public Name getName() { return name; }
    // grade, email 映射略
}
  • @DependentObject 標記主鍵類別
  • @Dependent + @DependentAttribute 將主鍵類別屬性展開映射為資料表多欄位 (FIRST, LAST)

3. 會話 Bean 介面 StudentDAO.java

@Remote
public interface StudentDAO {
    void create(String first, String last, String grade, String email);
    Student find(Name name);
    List findByFirstName(String name);
    List findByLastName(String name);
    List findByEmail(String email);
    void merge(Student s);
}

4. 會話 Bean 實作 StudentDAOBean.java

@Stateless
public class StudentDAOBean implements StudentDAO {
    @Inject EntityManager manager;

    public void create(String first, String last, String grade, String email) {
        Student s = new Student();
        s.setName(new Name(first, last));
        s.setGrade(grade); s.setEmail(email);
        manager.create(s);
    }
    public Student find(Name name) { return manager.find(Student.class, name); }
    public List findByFirstName(String n) {
        return manager.createQuery("from Student s where s.name.last = :name")
                      .setParameter("name", n).listResults();
    }
    // 其他查詢略
    public void merge(Student s) { manager.merge(s); }
}

5. 客戶端測試 Client.java

InitialContext ctx = new InitialContext();
StudentDAO dao = (StudentDAO) ctx.lookup(StudentDAO.class.getName());

dao.create("晁", "岳攀", "8", "smallnest@kuaff.com");
dao.create("朱", "立煥", "6", "zhuzhu@kuaff.com");

Name name = new Name("朱", "立煥");
Student s = dao.find(name);
System.out.printf("%s %s的email:%s%n", s.getName().getFirst(), s.getName().getLast(), s.getEmail());

部署與驗證

  1. 啟動 JBoss:{$JBOSS_HOME}/bin/run.bat -c all
  2. 管理主控台:https://localhost:8080/jmx-console/ 檢視部署狀態
  3. 執行 Client 驗證組合主鍵查詢正確性

關鍵注意事項

  • 組合主鍵類別不可為實體 Bean(標記 @DependentObject 而非 @Entity)
  • hashCode/equals 實作必須穩定、一致,影響集合操作與快取正確性
  • JPQL 查詢中透過 s.name.last 路徑導航存取組合主鍵屬性
  • 適用於自然主鍵(業務意義明確)場景;代理主鍵仍建議用單一自動生成欄位
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved