多對多關係需透過一張中間關聯表實現。本例中:
t_customers:客戶表t_addresses:地址表t_customers_addresses:關聯表,含 customer_id、address_id 兩個外鍵
@Entity
@Table(name = "t_customers")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(
name = "t_customers_addresses",
joinColumns = @JoinColumn(name = "customer_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id")
)
private Collection<Address> addresses;
// Getter/Setter 略...
}
@Entity
@Table(name = "t_addresses")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String addressLine;
private String country;
private String postCode;
@ManyToMany(mappedBy = "addresses")
private Collection<Customer> customers;
// Getter/Setter 略...
}
@ManyToMany:宣告多對多關係。@JoinTable:指定關聯表名稱與雙向外鍵對應關係。mappedBy = "addresses":表示由 Customer 端維護關係,Address 端僅映射。cascade = CascadeType.PERSIST:持久化 Customer 時自動級聯持久化關聯的 Address。Customer customer = new Customer();
customer.setName("微軟11");
List<Address> addresses = new ArrayList<>();
Address addr1 = new Address();
addr1.setAddressLine("address1");
addr1.setCountry("中國");
addr1.setPostCode("12345678");
addresses.add(addr1);
Address addr2 = new Address();
addr2.setAddressLine("address2");
addr2.setCountry("美國");
addr2.setPostCode("4321");
addresses.add(addr2);
customer.setAddresses(addresses);
em.persist(customer); // 級聯儲存關聯地址
雙向關係時,建議在業務邏輯中同步維護兩端集合(如 customer.getAddresses().add(addr); addr.getCustomers().add(customer);),確保物件圖一致性。