這是個(gè)系列教程,看完這個(gè)世杀,你對(duì)JavaEE注解,包括spring肝集、hibernate瞻坝,RESTFul web service ,JAXB, 以及junit注解將會(huì)有一個(gè)全面的了解杏瞻。
英文原版網(wǎng)址在這里 我們不光是spring網(wǎng)站的搬運(yùn)工@農(nóng)夫山泉水所刀,實(shí)際上,翻譯過程中我保證準(zhǔn)確同時(shí)捞挥,加入了自己的理解浮创。
Hibernate JPA Annotations - Contents:
@Entity
import javax.persistence.Entity;
@Table
import javax.persistence.Table;
@Column
import javax.persistence.Column;
@Id
import javax.persistence.Id;
@GeneratedValue
import javax.persistence.GeneratedValue;
@Version
import javax.persistence.Version;
@OrderBy
import javax.persistence.OrderBy;
@Transient
import javax.persistence.Transient;
@Lob
import javax.persistence.Lob;
Hibernate Association Mapping Annotations
@OneToOne
import javax.persistence.OneToOne;
@ManyToOne
import javax.persistence.ManyToOne;
@OneToMany
import javax.persistence.OneToMany;
@ManyToMany
import javax.persistence.ManyToMany;
@PrimaryKeyJoinColumn
import javax.persistence.PrimaryKeyJoinColumn;
@JoinColumn
import javax.persistence.JoinColumn;
@JoinTable
import javax.persistence.JoinTable;
@MapsId
import javax.persistence.MapsId;
Hibernate Inheritance Mapping Annotations
@Inheritance
import javax.persistence.Inheritance;
@DiscriminatorColumn
import javax.persistence.DiscriminatorColumn;
@DiscriminatorValue
import javax.persistence.DiscriminatorValue;
@Entity,@Table,@Colume,@Id,@GeneratedValue略
@OrderBy(用于One-to-Many等關(guān)聯(lián)表中集合的排序)
@OrderBy("firstName asc")
private Set contacts;
@Transient 字段不會(huì)更新到數(shù)據(jù)庫
@Lob:二進(jìn)制數(shù)據(jù)
hibernate的注解就這么完了嗎?
hibernate注解的<u>重難點(diǎn)</u>在于多表之間的關(guān)系:
栗子來了:
company - companydetail : one-to-one砌函,共享相同主鍵
contact - contactDetail : 通過外鍵連接的one-to-one
contact-company : 外鍵連接的many-to-one, contact作為owner
company-companyStatus : 外鍵連接的many-to-one斩披,company作為owner
one-to-one tips:
共享相同主鍵的用@PrimaryKeyJoinColumn
一方持有另一方外鍵,用 @JoinColumn & @OneToOne和 mappedBy屬性
兩個(gè)Entity通過一個(gè)中間表聯(lián)系讹俊,使用@JoinTable and mappedBy
共享鍵用@MapsId
one-to-one
@Entity
@Table(name = "company")
public class Company implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue
private int id;
@OneToOne(cascade = CascadeType.MERGE)
@PrimaryKeyJoinColumn
private CompanyDetail companyDetail;
...
}
@Entity
@Table(name = "companyDetail")
public class CompanyDetail implements Serializable {
@Id
@Column(name = "id")
private int id;
...
}
@Entity
@Table(name = "contactDetail")
public class ContactDetail implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue
private int id;
@OneToOne
@MapsId
@JoinColumn(name = "contactId")
private Contact contact;
...
}
@Entity
@Table(name = "contact")
public class Contact implements Serializable {
@Id
@Column(name = "ID")
@GeneratedValue
private Integer id;
@OneToOne(mappedBy = "contact", cascade = CascadeType.ALL)
private ContactDetail contactDetail;
....
}
cascade(級(jí)聯(lián))級(jí)聯(lián)在編寫觸發(fā)器時(shí)經(jīng)常用到垦沉,觸發(fā)器的作用是當(dāng) 主控表信息改變時(shí),用來保證其關(guān)聯(lián)表中數(shù)據(jù)同步更新仍劈。若對(duì)觸發(fā)器來修改或刪除關(guān)聯(lián)表相記錄厕倍,必須要?jiǎng)h除對(duì)應(yīng)的關(guān)聯(lián)表信息,否則贩疙,會(huì)存有臟數(shù)據(jù)讹弯。所以,適當(dāng)?shù)淖龇ㄊ钦饨Γ瑒h除主表的同時(shí)组民,關(guān)聯(lián)表的信息也要同時(shí)刪除,在hibernate中芍躏,只需設(shè)置cascade屬性值即可邪乍。
CascadeType.PERSIST:級(jí)聯(lián)新增(又稱級(jí)聯(lián)保存):對(duì)order對(duì)象保存時(shí)也對(duì)items里的對(duì)象也會(huì)保存。對(duì)應(yīng)EntityManager的presist方法
例子:只有A類新增時(shí),會(huì)級(jí)聯(lián)B對(duì)象新增庇楞。若B對(duì)象在數(shù)據(jù)庫存(跟新)在則拋異常(讓B變?yōu)槌志脩B(tài))
CascadeType.MERGE:級(jí)聯(lián)合并(級(jí)聯(lián)更新):若items屬性修改了那么order對(duì)象保存時(shí)同時(shí)修改items里的對(duì)象榜配。對(duì)應(yīng)EntityManager的merge方法
例子:指A類新增或者變化,會(huì)級(jí)聯(lián)B對(duì)象(新增或者變化)
CascadeType.REMOVE:級(jí)聯(lián)刪除:對(duì)order對(duì)象刪除也對(duì)items里的對(duì)象也會(huì)刪除吕晌。對(duì)應(yīng)EntityManager的remove方法
例子:REMOVE只有A類刪除時(shí)蛋褥,會(huì)級(jí)聯(lián)刪除B類;
CascadeType.REFRESH:級(jí)聯(lián)刷新:獲取order對(duì)象里也同時(shí)也重新獲取最新的items時(shí)的對(duì)象睛驳。對(duì)應(yīng)EntityManager的refresh(object)方法有效烙心。即會(huì)重新查詢數(shù)據(jù)庫里的最新數(shù)據(jù) (用的比較少)
CascadeType.ALL:以上四種都是
綜上所述:一般的,用CascadeType.MERGE:級(jí)聯(lián)合并(級(jí)聯(lián)更新)就能達(dá)到級(jí)更新同時(shí)又穩(wěn)定不報(bào)錯(cuò)乏沸。
@ManyToOne
tips:
Use @JoinColumn when foreign key is held by one of the entities.
Use @JoinTable for entities linked through an association table.
@Entity
@Table(name = "contact")
public class Contact implements Serializable {
@ManyToOne
@JoinColumn(name = "companyId")
private Company company;
...
}
@Entity
@Table(name = "company")
public class Company implements Serializable {
@ManyToOne
@JoinColumn(name = "statusId")
private CompanyStatus status;
...
}
@OneToMany
tips:
Use mappedBy attribute for bi-directional associations with ManyToOne being the owner.
OneToMany being the owner or unidirectional with foreign key - try to avoid such associations but can be achieved with @JoinColumn
@JoinTable for Unidirectional with association table
//Please see the many-to-one relationship between Contact and Company above. Company to Contact will be a one-to-many relationship. The owner of this relationship is Contact and hence we will use 'mappedBy' attribute in Company to make it bi-directional relationship.
@Entity
@Table(name = "company")
public class Company implements Serializable {
@OneToMany(mappedBy = "company", fetch = FetchType.EAGER)
@OrderBy("firstName asc")
private Set contacts;
...
}
@ManyToMany
tips:
Use @JoinTable for entities linked through an association table.
Use mappedBy attribute for bi-directional association.