您的位置:首页 > 移动开发

JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-005Table per subclass with joins(@Inheritance(strategy = InheritanceType.JOINED)、@PrimaryKeyJoinColumn、)

2016-04-07 22:09 761 查看
一、结构

The fourth option is to represent inheritance relationships as SQL foreign key associations. Every class/subclass that declares persistent properties—including abstract classes and even interfaces—has its own table.
Unlike the table-per-concrete-class strategy we mapped first, the table of a concrete @Entity here contains columns only for each non-inherited property, declared by the subclass itself, along with a primary key that is also a foreign key of the superclass table.



二、代码

1.

package org.jpwh.model.inheritance.joined;

import org.jpwh.model.Constants;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.validation.constraints.NotNull;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BillingDetails {

@Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id;

@NotNull
protected String owner;

// ...

protected BillingDetails() {
}

protected BillingDetails(String owner) {
this.owner = owner;
}

public Long getId() {
return id;
}

public String getOwner() {
return owner;
}

public void setOwner(String owner) {
this.owner = owner;
}
}


2.

package org.jpwh.model.inheritance.joined;

import javax.persistence.Entity;
import javax.validation.constraints.NotNull;

@Entity
public class BankAccount extends BillingDetails {

@NotNull
protected String account;

@NotNull
protected String bankname;

@NotNull
protected String swift;

// ...

public BankAccount() {
super();
}

public BankAccount(String owner, String account, String bankname, String swift) {
super(owner);
this.account = account;
this.bankname = bankname;
this.swift = swift;
}

public String getAccount() {
return account;
}

public void setAccount(String account) {
this.account = account;
}

public String getBankname() {
return bankname;
}

public void setBankname(String bankname) {
this.bankname = bankname;
}

public String getSwift() {
return swift;
}

public void setSwift(String swift) {
this.swift = swift;
}
}


3.

package org.jpwh.model.inheritance.joined;

import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.validation.constraints.NotNull;

@Entity
@PrimaryKeyJoinColumn(name = "CREDITCARD_ID")
public class CreditCard extends BillingDetails {

@NotNull
protected String cardNumber;

@NotNull
protected String expMonth;

@NotNull
protected String expYear;

// ...

public CreditCard() {
super();
}

public CreditCard(String owner, String cardNumber, String expMonth, String expYear) {
super(owner);
this.cardNumber = cardNumber;
this.expMonth = expMonth;
this.expYear = expYear;
}

public String getCardNumber() {
return cardNumber;
}

public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}

public String getExpMonth() {
return expMonth;
}

public void setExpMonth(String expMonth) {
this.expMonth = expMonth;
}

public String getExpYear() {
return expYear;
}

public void setExpYear(String expYear) {
this.expYear = expYear;
}
}


4.The primary key columns of the BANKACCOUNT and CREDITCARD tables each also have a foreign key constraint referencing the primary key of the BILLINGDETAILS table.Hibernate relies on an SQL outer join for select bd from BillingDetails bd :

select
BD.ID, BD.OWNER,
CC.EXPMONTH, CC.EXPYEAR, CC.CARDNUMBER,
BA.ACCOUNT, BA.BANKNAME, BA.SWIFT,
case
when CC.CREDITCARD_ID is not null then 1
when BA.ID is not null then 2
when BD.ID is not null then 0
end
from BILLINGDETAILS BD
left outer join CREDITCARD CC on BD.ID = CC.CREDITCARD_ID
left outer join BANKACCOUNT BA on BD.ID = BA.ID


For a narrow subclass query like select cc from CreditCard cc , Hibernate uses an inner join:

select
CREDITCARD_ID, OWNER, EXPMONTH, EXPYEAR, CARDNUMBER
from
CREDITCARD
inner join BILLINGDETAILS on CREDITCARD_ID=ID


三、优缺点

1.优点

(1)The primary advantage of this strategy is that it normalizes the SQL schema.Schema evolution and integrity-constraint definition are straightforward. A foreign key referencing the table of a particular subclass may represent a polymorphic association to that particular subclass.

2.缺点

more difficult to implement by hand—even ad hoc reporting is more complex.

结论:even though this mapping strategy is deceptively simple, our experience is that performance can be unacceptable for complex class hierarchies. Queries always require a join across many tables, or many sequential reads.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: