实体Bean的连接策略(JOINED Strategy)
在上一篇文章中,使用单表策略将一个表从逻辑上分成了多个表。但这样可能会造成空巢字段,也就 是说,一个逻辑表只由部分字段组成,而物理的表的很多字段的值就会为null。为了解决这个问题,可以 将t_accounts表物理地分成多个表。为了与t_accounts表进行对比,新建一个t_myaccounts表,结构如图 1所示。
图1 t_myaccounts表
从t_myaccounts的结构可以看出,在该表中只包含了t_accounts表的前三个字段,而后两个在逻辑上 分到了不同的表,因此,首先要建立两个物理表:t_checkingaccount和t_savingsaccount。这两个表的 结构如下:
图2 t_checkingaccount表
图3 t_savingsaccount表
在t_checkingaccount和t_savingsaccount表中都有一个account_id,这个account_id的值依赖于 t_myaccounts表中的account_id。
下面先来编写与t_myaccounts对应的实体Bean,代码如下:
package entity;import javax.persistence.Column;import javax.persistence.DiscriminaTorColumn;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Inheritance;import javax.persistence.InheritanceType;import javax.persistence.Table;@Entity@Table(name="t_myaccounts")@Inheritance(strategy=InheritanceType.JOINED)public class Account{ protected String id; protected float balance; protected String type; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="account_id") public String getId() { return id; } public void setId(String id) { this.id = id; } public float getBalance() { return balance; } public void setBalance(float balance) { this.balance = balance; } @Column(name="account_type") public String getType() { return type; } public void setType(String type) { this.type = type; }}
从上面的代码可以看出,只使用了@Inheritance对实体Bean进行注释。
下面编写MyCheckingAccount和MySavingsAccount类的代码:
MyCheckingAccount类的代码:
package entity;import javax.persistence.Column;import javax.persistence.DiscriminaTorValue;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.PrimaryKeyJoinColumn;import javax.persistence.Table;@Entity@Table(name="t_checkingaccount")// 指定与Account类共享的主键名@PrimaryKeyJoinColumn(name="account_id") public class MyCheckingAccount extends Account{ private double overdraftLimit; public MyCheckingAccount() { // 为account_type字段赋默认值 setType("C"); } @Column(name="overdraft_limit") public double getOverdraftLimit() { return overdraftLimit; } public void setOverdraftLimit(double overdraftLimit) { this.overdraftLimit = overdraftLimit; }}
MySavingsAccount类的代码:
package entity;import javax.persistence.Column;import javax.persistence.DiscriminaTorValue;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.PrimaryKeyJoinColumn;import javax.persistence.Table;@Entity@Table(name="t_savingsaccount")@PrimaryKeyJoinColumn(name="account_id") public class MySavingsAccount extends Account{ private double interestRate; public MySavingsAccount() { // 为account_type字段赋默认值 setType("S"); } @Column(name="interest_rate") public double getInterestRate() { return interestRate; } public void setInterestRate(double interestRate) { this.interestRate = interestRate; } }
在上面的代码中使用构造方法来初始化了t_myaccounts表的account_type字段的值。
可以使用下面的代码进行测试:
System.out.println(((MyCheckingAccount)em.createQuery("from MyCheckingAccount where id=12") .getSingleResult()).getBalance());MyCheckingAccount ca = new MyCheckingAccount();ca.setBalance(342);ca.setOverdraftLimit(120);em.persist(ca);MySavingsAccount sa = new MySavingsAccount();sa.setBalance(200);sa.setInterestRate(321);em.persist(sa);
我诚恳地希望能够获得你的原谅。只是你懂得的,对于有一些委屈,