Hibernate3註解 收藏
一、@Entity(name="EntityName")
必須,name爲可選,對應數據庫中一的個表java
二、@Table(name="",catalog="",schema="")
可選,一般和@Entity配合使用,只能標註在實體的class定義處,表示實體對應的數據庫表的信息
name:可選,表示表的名稱.默認地,表名和實體名稱一致,只有在不一致的狀況下才須要指定表名
catalog:可選,表示Catalog名稱,默認爲Catalog("").
schema:可選,表示Schema名稱,默認爲Schema("").spring
三、@id
必須
@id定義了映射到數據庫表的主鍵的屬性,一個實體只能有一個屬性被映射爲主鍵.置於getXxxx()前.數據庫
四、@GeneratedValue(strategy=GenerationType,generator="")
可選
strategy:表示主鍵生成策略,有AUTO,INDENTITY,SEQUENCE 和 TABLE 4種,分別表示讓ORM框架自動選擇,
根據數據庫的Identity字段生成,根據數據庫表的Sequence字段生成,以有根據一個額外的表生成主鍵,默認爲AUTO
generator:表示主鍵生成器的名稱,這個屬性一般和ORM框架相關,例如,Hibernate能夠指定uuid等主鍵生成方式.
示例:
@Id
@GeneratedValues(strategy=StrategyType.SEQUENCE)
public int getPk() {
return pk;
}api
五、@Basic(fetch=FetchType,optional=true)
可選
@Basic表示一個簡單的屬性到數據庫表的字段的映射,對於沒有任何標註的getXxxx()方法,默認即爲@Basic
fetch: 表示該屬性的讀取策略,有EAGER和LAZY兩種,分別表示主支抓取和延遲加載,默認爲EAGER.
optional:表示該屬性是否容許爲null,默認爲true
示例:
@Basic(optional=false)
public String getAddress() {
return address;
}session
六、@Column
可選
@Column描述了數據庫表中該字段的詳細定義,這對於根據JPA註解生成數據庫表結構的工具很是有做用.
name:表示數據庫表中該字段的名稱,默認情形屬性名稱一致
nullable:表示該字段是否容許爲null,默認爲true
unique:表示該字段是不是惟一標識,默認爲false
length:表示該字段的大小,僅對String類型的字段有效
insertable:表示在ORM框架執行插入操做時,該字段是否應出現INSETRT語句中,默認爲true
updateable:表示在ORM框架執行更新操做時,該字段是否應該出如今UPDATE語句中,默認爲true.對於一經建立就不能夠更改的字段,該屬性很是有用,如對於birthday字段.
columnDefinition:表示該字段在數據庫中的實際類型.一般ORM框架能夠根據屬性類型自動判斷數據庫中字段的類型,可是對於Date類型仍沒法肯定數據庫中字段類型到底是DATE,TIME仍是TIMESTAMP.此外,String的默認映射類型爲VARCHAR,若是要將String類型映射到特定數據庫的BLOB或TEXT字段類型,該屬性很是有用.
示例:
@Column(name="BIRTH",nullable="false",columnDefinition="DATE")
public String getBithday() {
return birthday;
}app
七、@Transient
可選
@Transient表示該屬性並不是一個到數據庫表的字段的映射,ORM框架將忽略該屬性.
若是一個屬性並不是數據庫表的字段映射,就務必將其標示爲@Transient,不然,ORM框架默認其註解爲@Basic
示例:
//根據birth計算出age屬性
@Transient
public int getAge() {
return getYear(new Date()) - getYear(birth);
}框架
八、@ManyToOne(fetch=FetchType,cascade=CascadeType)
可選
@ManyToOne表示一個多對一的映射,該註解標註的屬性一般是數據庫表的外鍵
optional:是否容許該字段爲null,該屬性應該根據數據庫表的外鍵約束來肯定,默認爲true
fetch:表示抓取策略,默認爲FetchType.EAGER
cascade:表示默認的級聯操做策略,能夠指定爲ALL,PERSIST,MERGE,REFRESH和REMOVE中的若干組合,默認爲無級聯操做
targetEntity:表示該屬性關聯的實體類型.該屬性一般沒必要指定,ORM框架根據屬性類型自動判斷targetEntity.
示例:
//訂單Order和用戶User是一個ManyToOne的關係
//在Order類中定義
@ManyToOne()
@JoinColumn(name="USER")
public User getUser() {
return user;
}dom
九、@JoinColumn
可選
@JoinColumn和@Column相似,介量描述的不是一個簡單字段,而一一個關聯字段,例如.描述一個@ManyToOne的字段.
name:該字段的名稱.因爲@JoinColumn描述的是一個關聯字段,如ManyToOne,則默認的名稱由其關聯的實體決定.
例如,實體Order有一個user屬性來關聯實體User,則Order的user屬性爲一個外鍵,
其默認的名稱爲實體User的名稱+下劃線+實體User的主鍵名稱
示例:
見@ManyToOneide
十、@OneToMany(fetch=FetchType,cascade=CascadeType)
可選
@OneToMany描述一個一對多的關聯,該屬性應該爲集體類型,在數據庫中並無實際字段.
fetch:表示抓取策略,默認爲FetchType.LAZY,由於關聯的多個對象一般沒必要從數據庫預先讀取到內存
cascade:表示級聯操做策略,對於OneToMany類型的關聯很是重要,一般該實體更新或刪除時,其關聯的實體也應當被更新或刪除
例如:實體User和Order是OneToMany的關係,則實體User被刪除時,其關聯的實體Order也應該被所有刪除
示例:
@OneTyMany(cascade=ALL)
public List getOrders() {
return orders;
}工具
十一、@OneToOne(fetch=FetchType,cascade=CascadeType)
可選
@OneToOne描述一個一對一的關聯
fetch:表示抓取策略,默認爲FetchType.LAZY
cascade:表示級聯操做策略
示例:
@OneToOne(fetch=FetchType.LAZY)
public Blog getBlog() {
return blog;
}
十二、@ManyToMany
可選
@ManyToMany 描述一個多對多的關聯.多對多關聯上是兩個一對多關聯,可是在ManyToMany描述中,中間表是由ORM框架自動處理
targetEntity:表示多對多關聯的另外一個實體類的全名,例如:package.Book.class
mappedBy:表示多對多關聯的另外一個實體類的對應集合屬性名稱
示例:
User實體表示用戶,Book實體表示書籍,爲了描述用戶收藏的書籍,能夠在User和Book之間創建ManyToMany關聯
@Entity
public class User {
private List books;
@ManyToMany(targetEntity=package.Book.class)
public List getBooks() {
return books;
}
public void setBooks(List books) {
this.books=books;
}
}
@Entity
public class Book {
private List users;
@ManyToMany(targetEntity=package.Users.class, mappedBy="books")
public List getUsers() {
return users;
}
public void setUsers(List users) {
this.users=users;
}
}
兩個實體間相互關聯的屬性必須標記爲@ManyToMany,並相互指定targetEntity屬性,
須要注意的是,有且只有一個實體的@ManyToMany註解須要指定mappedBy屬性,指向targetEntity的集合屬性名稱
利用ORM工具自動生成的表除了User和Book表外,還自動生成了一個User_Book表,用於實現多對多關聯
1三、@MappedSuperclass
可選
@MappedSuperclass能夠將超類的JPA註解傳遞給子類,使子類可以繼承超類的JPA註解
示例:
@MappedSuperclass
public class Employee() {
....
}
@Entity
public class Engineer extends Employee {
.....
}
@Entity
public class Manager extends Employee {
.....
}
1四、@Embedded
可選
@Embedded將幾個字段組合成一個類,並做爲整個Entity的一個屬性.
例如User包括id,name,city,street,zip屬性.
咱們但願city,street,zip屬性映射爲Address對象.這樣,User對象將具備id,name和address這三個屬性.
Address對象必須定義爲@Embededable
示例:
@Embeddable
public class Address {city,street,zip}
@Entity
public class User {
@Embedded
public Address getAddress() {
..........
}
}
如今,讓咱們來動手使用Hibernate Annotation。
安裝 Hibernate Annotation
要使用 Hibernate Annotation,您至少須要具有 Hibernate 3.2和Java 5。能夠從 Hibernate 站點 下載 Hibernate 3.2 和 Hibernate Annotation庫。除了標準的 Hibernate JAR 和依賴項以外,您還須要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。若是您正在使用 Maven,只須要向 POM 文件添加相應的依賴項便可,以下所示:
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
...
下一步就是獲取 Hibernate 會話工廠。儘管無需驚天的修改,但這一工做與使用 Hibernate Annotations有所不一樣。您須要使用 AnnotationConfiguration 類來創建會話工廠:
sessionFactory = new
AnnotationConfiguration().buildSessionFactory();
儘管一般使用 <mapping> 元素來聲明持久性類,您仍是須要在 Hibernate 配置文件(一般是 hibernate.cfg.xml)中聲明持久性類:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.onjava.modelplanes.domain.PlaneType"/>
<mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
</session-factory>
</hibernate-configuration>
近期的許多 Java 項目都使用了輕量級的應用框架,例如 Spring。若是您正在使用 Spring 框架,可使用 AnnotationSessionFactoryBean 類輕鬆創建一個基於註釋的 Hibernate 會話工廠,以下所示:
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
...
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.onjava.modelplanes.domain.PlaneType</value>
<value>com.onjava.modelplanes.domain.ModelPlane</value>
...
</list>
</property>
</bean>
第一個持久性類
既然已經知道了如何得到註釋所支持的 Hibernate 會話,下面讓咱們來了解一下帶註釋的持久性類的狀況:
像在其餘任何 Hibernate應用程序中同樣,帶註釋的持久性類也是普通 POJO。差很少能夠說是。您須要向 Java 持久性 API (javax.persistence.*)添加依賴項,若是您正在使用任何特定於 Hibernate的擴展,那極可能就是 Hibernate Annotation 程序包(org.hibernate.annotations.*),但除此以外,它們只是具有了持久性註釋的普通 POJO 。下面是一個簡單的例子:
@Entity
public class ModelPlane {
private Long id;
private String name;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
正像咱們所提到的,這很是簡單。@Entity 註釋聲明該類爲持久類。@Id 註釋能夠代表哪一種屬性是該類中的獨特標識符。事實上,您既能夠保持字段(註釋成員變量),也能夠保持屬性(註釋getter方法)的持久性。後文中將使用基於屬性的註釋。基於註釋的持久性的優勢之一在於大量使用了默認值(最大的優勢就是 「慣例優先原則(convention over configuration)」)。例如,您無需說明每一個屬性的持久性——任何屬性都被假定爲持久的,除非您使用 @Transient 註釋來講明其餘狀況。這簡化了代碼,相對使用老的 XML 映射文件而言也大幅地減小了輸入工做量。
生成主鍵
Hibernate 可以出色地自動生成主鍵。Hibernate/EBJ 3 註釋也能夠爲主鍵的自動生成提供豐富的支持,容許實現各類策略。下面的示例說明了一種經常使用的方法,其中 Hibernate 將會根據底層數據庫來肯定一種恰當的鍵生成策略:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
定製表和字段映射
默認狀況下,Hibernate 會將持久類以匹配的名稱映射到表和字段中。例如,前一個類能夠與映射到以以下代碼建立的表中:
CREATE TABLE MODELPLANE
(
ID long,
NAME varchar
)
若是您是本身生成並維護數據庫,那麼這種方法頗有效,經過省略代碼能夠大大簡化代碼維護。然而,這並不能知足全部人的需求。有些應用程序須要訪問外部數據庫,而另外一些可能須要聽從公司的數據庫命名慣例。若是有必要,您可使用 @Table 和 @Column 註釋來定製您本身的持久性映射,以下所示:
@Entity
@Table(name="T_MODEL_PLANE")
public class ModelPlane {
private Long id;
private String name;
@Id
@Column(name="PLANE_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name="PLANE_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
該內容將映射到下表中:
CREATE TABLE T_MODEL_PLANE
(
PLANE_ID long,
PLANE_NAME varchar
)
也可使用其餘圖和列的屬性來定製映射。這使您能夠指定諸如列長度、非空約束等詳細內容。Hibernate支持大量針對這些註釋的屬性。下例中就包含了幾種屬性:
...
@Column(name="PLANE_ID", length=80, nullable=true)
public String getName() {
return name;
}
...
映射關係
Java 持久性映射過程當中最重要和最複雜的一環就是肯定如何映射表間的關係。像其餘產品同樣, Hibernate 在該領域中提供了高度的靈活性,但倒是以複雜度的增長爲代價。咱們將經過研究幾個常見案例來了解如何使用註釋來處理這一問題。
其中一種最經常使用的關係就是多對一的關係。假定在以上示例中每一個 ModelPlane 經過多對一的關係(也就是說,每一個飛機模型只與一種飛機類型創建聯繫,儘管指定的飛機類型能夠與七種飛機模型創建聯繫)來與 PlaneType 創建聯繫。可以下進行映射:
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
public PlaneType getPlaneType() {
return planeType;
}
CascadeType 值代表 Hibernate 應如何處理級聯操做。
另外一種經常使用的關係與上述關係相反:一對多再對一關係,也稱爲集合。在老式的 Hibernate 版本中進行映射或使用註釋時,集合使人頭疼,這裏咱們將簡要加以探討,以使您瞭解如何處理集合,例如,在以上示例中每一個 PlaneType 對象均可能會包含一個 ModelPlanes 集合。可映射以下:
@OneToMany(mappedBy="planeType",
cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
@OrderBy("name")
public List<ModelPlane> getModelPlanes() {
return modelPlanes;
}
命名查詢
Hibernate 最優秀的功能之一就在於它可以在您的映射文件中聲明命名查詢。隨後便可經過代碼中的名稱調用此類查詢,這使您能夠專一於查詢,而避免了 SQL 或者 HQL 代碼分散於整個應用程序中的狀況。
也可使用註釋來實現命名查詢,可使用 @NamedQueries 和 @NamedQuery 註釋,以下所示:
@NamedQueries(
{
@NamedQuery(
name="planeType.findById",
query="select p from PlaneType p left join fetch p.modelPlanes where id=:id"
),
@NamedQuery(
name="planeType.findAll",
query="select p from PlaneType p"
),
@NamedQuery(
name="planeType.delete",
query="delete from PlaneType where id=:id"
)
}
)
一旦完成了定義,您就能夠像調用其餘任何其餘命名查詢同樣來調用它們。
結束語
Hibernate 3 註釋提供了強大而精緻的 API,簡化了 Java 數據庫中的持久性代碼,本文中只進行了簡單的討論。您能夠選擇聽從標準並使用 Java 持久性 API,也能夠利用特定於 Hibernate的擴展,這些功能以損失可移植性爲代價提供了更爲強大的功能和更高的靈活性。不管如何,經過消除對 XML 映射文件的需求,Hibernate 註釋將簡化應用程序的維護,同時也可使您對EJB 3 有初步認識。來試試吧!
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/dingqinghu/archive/2011/03/25/6275798.aspx
註解映射必須知足兩大條件:Hibernate3.2以上版本和JSEE 5。
@Entity 類註釋,全部要持久化的類都要有
@Entity
public class Org implements java.io.Serializable {
}
@Id 主鍵
@Id
@GeneratedValue
private String orgId;
private String orgName;
@Column(name="...") 該屬性對應表中的字段是什麼,沒有name表示同樣
@Table 對象與表映射
@UniqueConstraint 惟一約束
@Version 方法和字段級,樂觀鎖用法,返回數字和timestamp,數字爲首選
@Transient 暫態屬性,表示不須要處理
@Basic 最基本的註釋。有兩個屬性:fetch是否延遲加載,optional是否容許null
@Enumerated 枚舉類型
@Temporal 日期轉換。默認轉換Timestamp
@Lob 一般與@Basic同時使用,提升訪問速度。
@Embeddable 類級,表可嵌入的
@Embedded 方法字段級,表被嵌入的對象和@Embeddable一塊兒使用
@AttributeOverrides 屬性重寫
@AttributeOverride 屬性重寫的內容和@AttributeOverrides一塊兒嵌套使用
@SecondaryTables 多個表格映射
@SecondaryTable 定義輔助表格映射和@SecondaryTables一塊兒嵌套使用
@GeneratedValue 標識符生成策略,默認Auto
表與表關係映射
@OneToOne:一對一映射。它包含五個屬性:
targetEntity:關聯的目標類
Cascade:持久化時的級聯操做,默認沒有
fetch:獲取對象的方式,默認EAGER
Optional:目標對象是否容許爲null,默認容許
mappedBy:定義雙向關聯中的從屬類。
單向:
@JoinColumn:定義外鍵(主表會多一字段,作外鍵)
@OneToMany:一對多映射;@ManyToOne:多對一映射
單向一對多:
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="book_oid")/**book:表;oid:book表的主鍵;無name會按此規則自動生成*/
單向多對一:
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="author_oid")
關聯表格一對多:
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(joinColumn={@JoinColumn(name="BOOK_OBJECT_OID")},inverseJoinColumns={@JoinColumn(name="AUTHER_OBJECT_OID")})
雙向一對多或多對一:
不須要多一張表,只是使用mappedBy:使用在One一方,值爲One方類名錶示Many的從屬類。
@Entity
Java代碼
@Entity
public class Org implements java.io.Serializable {
// Fields
@Id
@GeneratedValue
private String orgId;
private String orgName;
@OneToMany(mappedBy = "org")
private List<Department> departments;
// Constructors
...
// Property accessors
...
}
@Entity public class Org implements java.io.Serializable { // Fields @Id @GeneratedValue private String orgId; private String orgName; @OneToMany(mappedBy = "org") private List<Department> departments; // Constructors ... // Property accessors ... }
@Entity
public class Department implements java.io.Serializable {
// Fields
@Id
@GeneratedValue
private String id;
private String name;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="org_orgId")
private Org org;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
// Constructors
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public Org getOrg() {
return org;
}
public void setOrg(Org org) {
this.org = org;
}
/** default constructor */
.
.
.
}
Java代碼
@Entity
public class Employee implements java.io.Serializable {
// Fields
@Id
@GeneratedValue
private String employeeId;
private String employeeName;
private String passWord;
private Integer age;
private Integer sex;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="department_id")
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
/** default constructor */
...
// Property accessors
...
}
@Entity public class Employee implements java.io.Serializable { // Fields @Id @GeneratedValue private String employeeId; private String employeeName; private String passWord; private Integer age; private Integer sex; @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="department_id") private Department department; public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } /** default constructor */ ... // Property accessors ... }
雙向多對多:@ManyToMany.單向多對多這裏不在贅述(沒有太多實際意義)
這個比較簡單,看下代碼就明白了:
@Entity
public class Book implements java.io.Serializable {
@Id
private int id;
private String name;
private float money;
@ManyToMany(cascade = CascadeType.ALL)
private List<Author> authors;
public List<Author> getAuthors() {
return authors;
}
public void setAuthors(List<Author> authors) {
this.authors = authors;
}
...
}
@Entity
public class Author implements java.io.Serializable {
@Id
private int id;
private String name;
private int age;
@ManyToMany(mappedBy="authors")
private List<Book> books;
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
...
}
基於註解的hibernate主鍵設置:@Id.
那麼它的生成規則是什麼呢?是由@GeneratedValue來規定的。
咱們先來看看它是如何定義的:
Java代碼
@Target({METHOD,FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue{
GenerationType strategy() default AUTO;
String generator() default "";
}
@Target({METHOD,FIELD}) @Retention(RUNTIME) public @interface GeneratedValue{ GenerationType strategy() default AUTO; String generator() default ""; }
Java代碼
public enum GenerationType{
TABLE,
SEQUENCE,
IDENTITY,
AUTO
}
public enum GenerationType{ TABLE, SEQUENCE, IDENTITY, AUTO }
如今咱們看到了,它提供了4種生成策略:
TABLE:使用一個特定的數據庫表格來保存標識符序列。
SEQUENCE:生成序列化標識符。
IDENTITY:標識符有數據庫自動生成(主要是自動增加型)
AUTO:標識符生成工做由hibernate自動處理。實際項目開發不建議使用。
注意:當主鍵爲int,而數據庫中又不是自動增加型時,使用@GeneratedValue是沒法正常工做的。
咱們也可使用下面的方式來本身指定咱們的主鍵值:
Java代碼
@GeneratedValue(generator = "c-assigned")
@GenericGenerator(name = "c-assigned", strategy = "assigned")
private String employeeId;
@GeneratedValue(generator = "c-assigned") @GenericGenerator(name = "c-assigned", strategy = "assigned") private String employeeId;
或者直接不要定義@GeneratedValue,只定義@Id效果也是同樣的。