轉載需要說明出處:http://blog.csdn.net/minimicall?viewmode=contents,http://cloudtrader.top/
1. 類代碼
EntityBase是其他實體類的基類。在這裏我們先將代碼貼出。需要說明的是,有些實體類是需要映射到數據庫的。需要JPA基礎,或者Hibernate基礎。
這個類就是包含一個Id,唯一標示、還有就是一個版本號。利於升級。
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)@MappedSuperclass
public abstract class EntityBase implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7893439827939854533L;
@Id
@Column(columnDefinition = "BINARY(16)", length = 16, updatable = false, nullable = false)
public UUID getId() {
ensureId();
return id;
}
@Version
private Long version;
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
@Override
public boolean equals(Object o) {
// generated by IDEA
if (this == o)
return true;
if (!(o instanceof EntityBase))
return false;
EntityBase that = (EntityBase) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
ensureId();
return id.hashCode();
}
// JPA
protected EntityBase() {
}
protected void setId(UUID id) {
this.id = id;
}
private void ensureId() {
if (id == null)
id = UUID.randomUUID();
}
private UUID id;
}
2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)註解說明
在JPA中,實體繼承關係的映射策略共有三種:單表繼承策略(table per class)、Joined策略(table per subclass)和Table_PER_Class策略。
下面我原本抄一篇別人的帖子。出處:http://zhuchengzzcc.iteye.com/blog/1679496
1.單表繼承策略
單表繼承策略,父類實體和子類實體共用一張數據庫表,在表中通過一列辨別字段來區別不同類別的實體。具體做法如下:
a.在父類實體的@Entity註解下添加如下的註解:
@Inheritance(Strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”辨別字段列名”)
@DiscriminatorValue(父類實體辨別字段列值)
b.在子類實體的@Entity註解下添加如下的註解:
@DiscriminatorValue(子類實體辨別字段列值)
定義了一個父類
- @Entity
- @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
- @Table(name = "WINDOW_FILE")
- @DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
- @DiscriminatorValue("WindowFile")
- public class WindowFile {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Integer id;
- @Basic
- @Column(name = "NAME")
- private String name;
- @Basic
- @Column(name = "TYPE")
- private String type;
- @Basic
- @Column(name = "DATE")
- private Date date;
- //省略get set
- }
後定義2個子類
- @Entity
- @DiscriminatorValue("Folder")
- public class Folder extends WindowFile {
- @Basic
- @Column(name = "FILE_COUNT")
- private Integer fileCount;
- //省略get set
- }
- @Entity
- @DiscriminatorValue("Document")
- public class Document extends WindowFile {
- @Basic
- @Column(name = "SIZE")
- private String size;
- //省略get set
- }
以上通過列DISCRIMINATOR的不同,區分具體父子實體。
實際表結構如下:
WINDOW_FILE DISCRIMINATOR,ID,NAME,DATE,TYPE,SIZE,FILE_COUNT
當你使用WindowFile實體時,實際表的字段爲DISCRIMINATOR='WindowFile',SIZE與FILE_COUNT永遠是空
當使用Folder實體時,DISCRIMINATOR='Folder',SIZE永遠是空,FILE_COUNT爲實際值。
Document同理,與Folder類似。
2.Joined策略
父類實體和子類實體分別對應數據庫中不同的表,子類實體的表中只存在其擴展的特殊屬性,父類的公共屬性保存在父類實體映射表中。具體做法:
@Inheritance(Strategy=InheritanceType.JOINED)
子類實體不需要特殊說明。
- @Entity
- @Table(name = "T_ANIMAL")
- @Inheritance(strategy = InheritanceType.JOINED)
- public class Animal {
- @Id
- @Column(name = "ID")
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Integer id;
- @Column(name = "NAME")
- private String name;
- @Column(name = "COLOR")
- private String color;
- //省略get set
- }
- @Entity
- @Table(name = "T_BIRD")
- @PrimaryKeyJoinColumn(name = "BIRD_ID")
- public class Bird extends Animal {
- @Column(name = "SPEED")
- private String speed;
- //省略get set
- }
- @Entity
- @Table(name = "T_DOG")
- @PrimaryKeyJoinColumn(name = "DOG_ID")
- public class Dog extends Animal {
- @Column(name = "LEGS")
- private Integer legs;
- //省略get set
- }
實際表結構如下:
T_ANIMAL ID,COLOR,NAME
T_BIRD SPEED,BIRD(既是外鍵,也是主鍵)
T_DOG LEGS,DOG_ID(既是外鍵,也是主鍵)
3.Table_PER_Class策略:
Table_PER_Class策略,父類實體和子類實體每個類分別對應一張數據庫中的表,子類表中保存所有屬性,包括從父類實體中繼承的屬性。具體做法:
只需在父類實體的@Entity註解下添加如下註解:
@Inheritance(Strategy=InheritanceType.TABLE_PER_CLASS)
- @Entity
- @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
- @Table(name = "T_VEHICLE")
- public class Vehicle { // 基類
- @Id
- // @GeneratedValue
- @Column(name = "ID")
- private Integer id;
- @Column(name = "SPEED")
- private Integer speed;// 速度
- //省略get set
- }
- @Entity
- @Table(name = "T_CAR")
- public class Car extends Vehicle {
- @Column(name = "ENGINE")
- private String engine;// 發動機
- //省略get set
- }
一旦使用這種策略就意味着你不能使用AUTO generator 和IDENTITY generator,即主鍵值不能採用數據庫自動生成。
實際表結構如下:
T_VEHICLE ID,SPEED
T_CAR ID,SPEED,ENGINE
3. @MappedSuperClass註解
@MappedSuperclass註解是爲了在繼承中,防止基類生成表格。在基類加上該標註,而不是@Entity,就可以只生成子類表,而子類表又含有基類的那些屬性(列)。
一樣爲了更好的理解這東西,我抄別人的啦:http://blog.163.com/zzf_fly/blog/static/209589158201362643027706/,別人已經寫的很好的,我就不想寫。貼在這裏主要是爲了連貫性:
實體類baseEntity.java
package com.rock.cft.hibernate;
import java.util.Date;
import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.MappedSuperclass;
//@MappedSuperclass 用在父類上面。當這個類肯定是父類時,加此標註。如果改成@Entity,則繼承後,多個類繼承,只會生成一個表,而不是多個繼承,生成多個表 @MappedSuperclass public abstract class BaseEntity { private Integer id;// 數據庫主鍵 private Date creationTime;//創建時間 private Date modificationTime;//修改時間 @Id @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Date getCreationTime() { return creationTime; } public void setCreationTime(Date creationTime) { this.creationTime = creationTime; } public Date getModificationTime() { return modificationTime; } public void setModificationTime(Date modificationTime) { this.modificationTime = modificationTime; }
}
實體類Test_No1.java
package com.rock.cft.test.model;
import java.io.Serializable; import java.util.Date;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table;
import com.rock.cft.hibernate.BaseEntity;
@Entity @Table(name="test_no2") public class Test_No1 extends BaseEntity implements Serializable { private String name; private int age;
public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }
}
實體類Test_NO2.java
package com.rock.cft.test.model;
import java.io.Serializable; import java.util.Date;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table;
import com.rock.cft.hibernate.BaseEntity;
@Entity @Table(name="test_no2") public class Test_NO2 extends BaseEntity implements Serializable { private Date testBri; private String testAdr; public Date getTestBri() { return testBri; } public void setTestBri(Date testBri) { this.testBri = testBri; } public String getTestAdr() { return testAdr; } public void setTestAdr(String testAdr) { this.testAdr = testAdr; }
}
這樣在生成表的時候只生成了:test_no1、test_no2兩張表,而且兩張表中都含有id、creationTime、modificationTime三個屬性
但是如果把@MappedSuperclass換成@Entity那麼就會另外在生成一張baseEntity的表
關於定義那些列的等具體細節,這裏就不再說明了。