Hibernate Annotation 關聯映射

hibernate Annotation標籤的使用:
1.帶註釋的持久性類也是普通 POJO,它們只是具有了持久性註釋的普通 POJO 。
2.事實上,您既能夠保持字段的持久性(註釋寫在成員變量之上),也能夠保持屬性(註釋寫在getter方法之上)的持久性。
經常使用的hibernate annotation標籤以下:
@Entity              --註釋聲明該類爲持久類。將一個Javabean類聲明爲一個實體的數據庫表映射類,最好實現序列化.此時,默認狀況下,全部的類屬性都爲映射到數據表的持久性字段.若在類中,添加另外屬性,而非映射來數據庫的,要用下面的Transient來註解.

@Table(name= "promotion_info")      --持久性映射的表(表名="promotion_info).@Table是類一級的註解,定義在@Entity下,爲實體bean映射表,目錄和schema的名字, 默認爲實體bean的類名,不帶包名.

@Id--註釋能夠代表哪一種屬性是該類中的獨特標識符(即至關於數據表的主鍵)。 
@GeneratedValue   --定義自動增加的主鍵的生成策略. 
@Transient             --將忽略這些字段和屬性,不用持久化到數據庫.適用於,在當前的持久類中,某些屬性不是用於映射到數據表,而是用於其它的業務邏輯須要,這時,須將這些屬性進行transient的註解.不然系統會因映射不到數據表相應字段而出錯. 
@Temporal(TemporalType.TIMESTAMP)--聲明時間格式 
@Enumerated         --聲明枚舉 
@Version                --聲明添加對樂觀鎖定的支持 
@OneToOne            --能夠創建實體bean之間的一對一的關聯 
@OneToMany          --能夠創建實體bean之間的一對多的關聯 
@ManyToOne          --能夠創建實體bean之間的多對一的關聯 
@ManyToMany        --能夠創建實體bean之間的多對多的關聯 
@Formula               --一個SQL表達式,這種屬性是隻讀的,不在數據庫生成屬性(可使用sum、average、max等) 
@OrderBy               --Many端某個字段排序(List)



Hibernate Annotation幾種關聯映射 數據庫

一對一(One-To-One) 數組

使用@OneToOne註解創建實體Bean之間的一對一關聯。一對一關聯有三種狀況:(1).關聯的實體都共享一樣的主鍵,(2).其中一個實體經過外鍵關聯到另外一個實體的主鍵(注意要模擬一對一關聯必須在外鍵列上添加惟一約束),(3).經過關聯表來保存兩個實體之間的鏈接關係(要模擬一對一關聯必須在每個外鍵上添加惟一約束)。 app

 

1.共享主鍵的一對一關聯映射: ide

@Entity oop

@Table(name="Test_Body") fetch

public class Body { 優化

   private Integer id; this

   private Heart heart; spa

   @Id hibernate

   public Integer getId() {

      return id;

   }

   public void setId(Integer id) {

      this.id = id;

   }

   @OneToOne

   @PrimaryKeyJoinColumn

   public Heart getHeart() {

      return heart;

   }

   public void setHeart(Heart heart) {

      this.heart = heart;

   }

}

@Entity

@Table(name="Test_Heart")

public class Heart {

   private Integer id;

   @Id

   public Integer getId() {

      return id;

   }

   public void setId(Integer id) {

      this.id = id;

   }

}

經過@PrimaryKeyJoinColumn批註定義了一對一關聯

 

2.使用外鍵進行實體一對一關聯:

@Entity

@Table(name="Test_Trousers")

public class Trousers {

   @Id

   public Integer id;

   @OneToOne

   @JoinColumn(name = "zip_id")

   public TrousersZip zip;

}

@Entity

@Table(name="Test_TrousersZip")

public class TrousersZip {

   @Id

   public Integer id;

   @OneToOne(mappedBy = "zip")

   public Trousers trousers;

}

上面的例子是指Trousers經過Trousers的外鍵列zip_id和TrousersZip關聯,@JoinColumn批註定義了聯接列,該批註和@Column批註有點相似,可是多了一個名爲referencedColumnName的參數。該參數定義了所關聯目標實體中的聯接列,注意,當referencedColumnName關聯到非主鍵列的時候,關聯的目標類必須實現Serializable,還要注意的是所映像的屬性對應單個列(不然映射無效)

一對一關聯多是雙向的,在雙向關聯中,有且僅有一端做爲主體(owner)端存在:主體端負責維護聯接列(即更新),對於不須要維護這種關係的從表則經過mappedNy屬性進行聲明。mappedBy的值指向主體的關聯屬性。例子中,mappedBy的值爲zip。最後,沒必要也不能再在被關聯端(ownedside)定義聯接列了,由於已經在主體端聲明瞭。

若是在主體沒有聲明@JoinColumn,系統自動進行處理:在主表(owner table)中將建立聯接列,列名爲:主體的關聯屬性名+下劃線+被關聯端的主鍵列名。上面的例子中是zip_id,由於Trousers中的關聯屬性名爲zip,TrousersZip的主鍵是id。

 

3.經過關聯表定義一對一關聯

@Entity

@Table(name="Test_People")

public class People {

   @Id

   public Integer id;

   @OneToOne

   @JoinTable(name ="TestPeoplePassports",

      joinColumns =@JoinColumn(name="people_fk"),

      inverseJoinColumns =@JoinColumn(name="passport_fk")

   )

   public Passport passport;

}

@Entity

@Table(name="Test_Passport")

public class Passport {

   @Id

   public Integer id;

   @OneToOne(mappedBy = "passport")

   public People people;

}

People經過名爲TestPeoplePassports的關聯表和Passport關聯。該關聯表擁有名爲passport_fk的外鍵列,該外鍵指向Passport表,該信息定義爲inverseJoinColoumns的屬性值,而people_fk外鍵列指向People表,該信息定義爲joinColumns的屬性值。

這種關聯多是雙向的,在雙向關聯中,有且僅有一端做爲主體(owner)端存在:主體端負責維護聯接列(即更新),對於不須要維護這種關係的從表則經過mappedNy屬性進行聲明。mappedBy的值指向主體的關聯屬性。例子中,mappedBy的值爲passport。最後,沒必要也不能再在被關聯端(ownedside)定義聯接列了,由於已經在主體端聲明瞭。

以上是一對一關聯的三種形式,下面介紹多對一關聯。

 

 

 

多對一(Many-to-One)

使用@ManyToOne批註來實現多對一關聯。

@ManyToOne批註有一個名爲targetEntity的參數,該參數定義了目標實體名,一般不須要定義該參數,由於在大部分狀況下默認值(表示關聯關係的屬性類型)就能夠很好的知足需求了。不過下面這種狀況下這個參數就顯得有意義了:使用接口做爲返回值而不是常見的實體。

@ManyToOne(targetEntity=CompanyImpl.class)

@JoinColoumn(name=」COPM_ID」)

Public Company getCompany(){

   return company;

}

多對一的配置方式有兩種:(1)經過@JoinColoumn映像(2)經過關聯表的方式來映像

 

(1)經過@JoinColoumn映射

SRD Framework中Company,Category例子:

Company:

@ManyToOne

   @JoinColumn(name = "CATEGORY_OPTION_ID")

   private Category category = null;

   Category:

@DiscriminatorValue("Category")

public class Category extends Option {

}

(2)經過關聯表映射

經過@JoinTable批註定義關聯表,該關聯表包含了指回實體表的外鍵(經過@JoinTable.joinColoumns)以及指向目標實體表的外鍵(經過@JoinTable.inverseJoinColoumns)

@Entity

@Table(name="Test_TreeType")

public class TreeType {

   private Integer id;

   private String name;

   private ForestType forestType;

   @ManyToOne(fetch = FetchType.LAZY)

   @JoinTable(name="Test_Tree_Forest",

      joinColumns = @JoinColumn(name="tree_id"),

      inverseJoinColumns = @JoinColumn(name="forest_id") )

public ForestType getForestType() {// forestType的getter,setter方法必須在這裏,不然會出錯

      return forestType;

   }

   public void setForestType(ForestType forestType) {

      this.forestType = forestType;

   }

   @Id

   @GeneratedValue

   public Integer getId() {

      return id;

   }

   public void setId(Integer id) {

      this.id = id;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

}

@Entity

@Table(name="Test_ForestType")

public class ForestType {

   private Integer id;

   private String name;

   private Set<TreeType> trees;

   @OneToMany(mappedBy="forestType")

public Set<TreeType> getTrees() {// trees的getter,setter方法必須在這裏,不然會出錯

      return trees;

   }

   public void setTrees(Set<TreeType> trees) {

      this.trees = trees;

   }

   @Id @GeneratedValue

   public Integer getId() {

      return id;

   }

   public void setId(Integer id) {

      this.id = id;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

}

 

一對多(One-to-Many)

使用@OneToMany批註可定義一對多關聯,一對多關聯能夠是雙向關聯。

在EJB3規範中多對一這端幾乎老是雙向關聯中的主體(owner)端,而一對多這端關聯批註爲@OneToMany(mappedBy...)

@Entity

Public class Troop{

   @OneToMany(mappedBy=」troop」)

Public Set<Soldier> getSoldiers(){

......

}

@Entity

Public class Soldier{

   @ManyToOne

   @JoinColumn(name=」troop_fk」)

Public Troop getTroop(){

......

}

Troop經過troop屬性和Soldier創建一對多的雙向關聯,在mappedBy端沒必要也不能再定義任何物理映射。

對於一對多的雙向映射,若是要一對多這一端維護關聯關係,你須要刪除mappedBy元素並將多對一這端的@JoinColoumn的insertable和updatabel設置爲false。這種方案不會獲得什麼明顯的優化,並且還會增長一些附加的UPDATE語句。

 

單向:

經過在被擁有的實體端(owned entity)增長一個外鍵列來實現一對多單向關聯是不多見的,也是不推薦的,建議經過一個聯接表來實現這種關聯(下面會講到)。

@JoinColoumn批註來描述這種單向關聯關係

@Entity

Public class Customer{

   @OneToMany

@JoinColoumn(name=」CUST_ID」)

Public Set<ticket> getTickets() {

......

}

@Entity

Public class Ticket{

   ...

}

Customer經過CUST_ID列和Ticket創建了單向關聯關係

經過關聯表處理單向關聯:

經過聯接表處理單向一對多關聯是首選方式,這種關聯經過@JoinTable批註進行描述

@Entity

Public class Trainer{

@OneToMany

@JoinTable(

   name = "TrainedMonkeys",

   jonColumns = {@JoinColumn(name = "trainer_id")},

   inverseJoinColumns = @JoinColumn(name = "monkey_id")

   )

public Set<Monkey> getTrainedMonkeys() {

      return trainedMonkeys;

   }

......

}

@Entity

public class Monkey {

...//no bidir

}

上面這個例子中,Trainer經過TrainedMonkeys表和Monkey創建了單向關聯,其中外鍵trainer_id關聯到Trainer(joinColoumn),而外鍵monkey_id關聯到Monkey(inversejionColoumns)

默認處理機制:

經過聯接表來創建單向一對多關聯不須要描述任何物理映像,表名由如下三個部分組成:主表(ownertable)表名+從表(the other side table)表名,指向主表的外鍵名:主表表名+下劃線+主表主鍵列名,指向從表的外鍵名:主表所對應實體的屬性名+下劃線+從表主鍵列名,指向從表的外鍵定義爲惟一約束,用來表示一對多的關聯關係。

@Entity

public class Trainer{

   @OneToMany

   Public Set<Tiger> getTrainedTigers(){

... ...

}

@Entity

public class Tiger{

.. ..//no bidir

}

上面這個例子中,Trainer和Tiger經過聯接表Trainer_Tiger創建單向關聯關係,其中外鍵trainer_id關聯到Trainer,而外鍵trainedTigers_id關聯到Tiger

 

多對多(Many-to-Many)

使用@ManyToMany批註可定義多對多關聯,同時,你也許要經過批註@JoinTable描述關聯表和關聯條件。若是是雙向關聯,其中一段必須定義爲Owner,另外一端必須定義爲inverse(在對關聯表進行更新操做時這一端將被忽略)

@Entity

public class Employer implements Serializable {

   private Integer id;

   private Collection employees;

   @ManyToMany(

targetEntity = org.hibernate.test.annotations.manytomany.Employee.class,

      cascade = {CascadeType.PERSIST, CascadeType.MERGE}

   )

   @JoinTable(

         name = "EMPLOYER_EMPLOYEE",

         joinColumns = {@JoinColumn(name = "EMPER_ID")},

         inverseJoinColumns = {@JoinColumn(name = "EMPEE_ID")}

   )

   public Collection getEmployees() {

      return employees;

   }

...

}

@Entity()

public class Employee implements Serializable {

   @ManyToMany(

         cascade = {CascadeType.PERSIST, CascadeType.MERGE},

         mappedBy = "employees"

         targetEntity = Employer.class

   )

public Collection<Employer> getEmployers() {

      return employers;

   }

.. ..

}

@JoinTable批註定義了聯接表的表名,聯接列數組,以及invers聯接列數組,後者是關聯表中關聯到Employee主鍵的列(the 「other side」)。

被關聯端沒必要也不能描述物理映射:只須要一個簡單的mappedBy參數,該參數包含了主體端的屬性名,這樣就綁定了雙方的關係。

默認值:

和其它許多批註同樣,在多對多關聯中不少值是自動生成,黨雙向多對多關聯中沒有定義任何物理映射時,Hibernate根據如下規則生成相應的值,關聯表名:主表表名+下劃線+從表表名,關聯到主表的外鍵名:主表名+下劃線+主表中的主鍵列名,關聯到從表的外鍵名:主表中用於關聯的屬性名+下劃線+從表的主鍵列名,以上規則對於雙向一對多關聯一樣同樣。

相關文章
相關標籤/搜索