當項目變得比較大的時候,如何還使用hbm.xml文件來配置Hibernate實體就會變得比較復雜。這里Hibernate提供了Annotation注解方式,使得Hibernate的映射文件變得很方便管理了。
這里簡單介紹Hibernate的Annotation注解
一、聲明實體
@Entity
對實體注釋。任何Hibernate映射對象都要有這個注釋
@Table
聲明此對象映射到數據庫的數據表,通過它可以為實體指定表(talbe),目錄(Catalog)和schema的名字。該注釋不是必須的,如果沒有則系統使用默認值(實體的短類名)。
@Version
該注釋可用於在實體Bean中添加樂觀鎖支持。
二、聲明主鍵
@Id
聲明此屬性為主鍵。該屬性值可以通過應該自身創建,但是Hibernate推薦通過Hibernate生成
@GeneratedValue
指定主鍵的生成策略。有如下四個值
TABLE:使用表保存id值
IDENTITY:identitycolumn
SEQUENCR :sequence
AUTO:根據數據庫的不同使用上面三個
三、聲明普通屬性
@Column
聲明該屬性與數據庫字段的映射關系。
1 @Column(nam=”category_name” length=20) 2 Public void getCategoryName(){ 3 Return this.categoryName; 4 }
注意:
1、 當POJO有屬性不需要映射的時候一定要用@Transitent修飾,該注釋表示此屬性與表沒有映射關系,只是一個暫時的屬性。
2、 @Lob注釋表示該屬性持久化為Blob或者Clob類型,具體取決於屬性的類型。
四、聲明關聯關系
一對多關聯關系
@OneToMany(mappedBy=” person”,cascade=CascadeType.ALL,fetch=FetchType.LAZY)
一對多聲明
@ManyToOne(cascade=CascadeType.REFRESH,)
@JoinColumn
多對一聲明 ,聲明為雙向關聯
一對一關聯關系
@OneToOne(optional= true,cascade =CascadeType.ALL, mappedBy = “person”)
一對一關聯聲明
@OneToOne(optional = false, cascade = CascadeType.REFRESH)
@JoinColumn(name = “Person_ID”, referencedColumnName = “personid”,unique = true)
聲明為雙向關聯
多對多關聯關系
@ManyToMany(mappedBy= “students”)
多對多關聯聲明。
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = “Teacher_Student”,
joinColumns = {@JoinColumn(name = “Teacher_ID”, referencedColumnName =“teacherid”)},
inverseJoinColumns = {@JoinColumn(name = “Student_ID”, referencedColumnName =“studentid”)})
實例:
有如下兩個實體,商品:Goods,分類Category。兩者是多對一的關聯關系。
使用Hibernate Annotation注解如下
1 Goods.java 2 3 @Entity 4 @Table(name = "goods", catalog = "test") 5 public class Goods implements java.io.Serializable { 6 7 private static final long serialVersionUID = 1L; 8 private String goodsId; 9 private Category category; 10 private String goodsName; 11 12 public Goods() { 13 } 14 15 /* 16 * 主鍵 17 * 生成策略為自動增長 18 * 唯一、長度為20 19 */ 20 @Id 21 @GeneratedValue 22 @Column(name = "goods_id", unique = true, nullable = false, length = 20) 23 public String getGoodsId() { 24 return this.goodsId; 25 } 26 27 public void setGoodsId(String goodsId) { 28 this.goodsId = goodsId; 29 } 30 31 /* 32 * 多對一關聯關系 33 * 延遲加載:fetch = FetchType.LAZY 34 * 引用外鍵:category_id 35 * 36 */ 37 @ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL) 38 @JoinColumn(name = "category_id") 39 public Category getCategory() { 40 return this.category; 41 } 42 43 public void setCategory(Category category) { 44 this.category = category; 45 } 46 47 @Column(name = "goods_name", nullable = false, length = 50) 48 public String getGoodsName() { 49 return this.goodsName; 50 } 51 52 public void setGoodsName(String goodsName) { 53 this.goodsName = goodsName; 54 } 55 56 }
Category.java
1 @Entity 2 @Table(name = "category", catalog = "test") 3 public class Category implements java.io.Serializable { 4 5 private static final long serialVersionUID = -1877960009126534682L; 6 7 private String categoryId; 8 private String categoryName; 9 private Set<Goods> goodses = new HashSet<Goods>(0); 10 11 public Category() { 12 } 13 14 /* 15 * 主鍵 16 * 生成策略為自動增長 17 * 唯一、長度為20 18 */ 19 @Id 20 @GeneratedValue 21 @Column(name = "category_id", unique = true, length = 10) 22 public String getCategoryId() { 23 return this.categoryId; 24 } 25 26 public void setCategoryId(String categoryId) { 27 this.categoryId = categoryId; 28 } 29 30 @Column(name = "category_name", length = 20) 31 public String getCategoryName() { 32 return this.categoryName; 33 } 34 35 public void setCategoryName(String categoryName) { 36 this.categoryName = categoryName; 37 } 38 39 /* 40 * 一對多關聯關系 41 * 級聯關系:cascade=CascadeType.ALL 42 * 延遲加載:fetch = FetchType.LAZY 43 * 映射:mappedBy = "category" 44 */ 45 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "category") 46 public Set<Goods> getGoodses() { 47 return this.goodses; 48 } 49 50 public void setGoodses(Set<Goods> goodses) { 51 this.goodses = goodses; 52 } 53 54 }
參考資料:http://www.cnblogs.com/chenssy/p/3149210.html
@Repository
spring 自 2.0 版本開始,陸續引入了一些注解用於簡化 Spring 的開發。@Repository注解便屬於最先引入的一批,它用於將數據訪問層 (DAO 層 ) 的類標識為 Spring Bean。具體只需將該注解標注在 DAO類上即可。同時,為了讓 Spring 能夠掃描類路徑中的類並識別出 @Repository 注解,需要在 XML 配置文件中啟用Bean 的自動掃描功能,這可以通過<context:component-scan/>實現。如下所示:
1 // 首先使用 @Repository 將 DAO 類聲明為 Bean 2 package bookstore.dao; 3 @Repository 4 public class UserDaoImpl implements UserDao{ …… } 5 6 // 其次,在 XML 配置文件中啟動 Spring 的自動掃描功能 7 <beans … > 8 …… 9 <context:component-scan base-package=”bookstore.dao” /> 10 …… 11 </beans>
如此,我們就不再需要在 XML 中顯式使用 <bean/> 進行Bean 的配置。Spring 在容器初始化時將自動掃描 base-package 指定的包及其子包下的所有 class文件,所有標注了 @Repository 的類都將被注冊為 Spring Bean。
為什么 @Repository 只能標注在 DAO 類上呢?這是因為該注解的作用不只是將類識別為Bean,同時它還能將所標注的類中拋出的數據訪問異常封裝為 Spring 的數據訪問異常類型。 Spring本身提供了一個豐富的並且是與具體的數據訪問技術無關的數據訪問異常結構,用於封裝不同的持久層框架拋出的異常,使得異常獨立於底層的框架。
@Service、@Controller 和 @Component 將類標識為Bean
Spring 2.5 在 @Repository的基礎上增加了功能類似的額外三個注解:@Component、@Service、@Constroller,它們分別用於軟件系統的不同層次:
- @Component 是一個泛化的概念,僅僅表示一個組件 (Bean) ,可以作用在任何層次。
- @Service 通常作用在業務層,但是目前該功能與 @Component 相同。
- @Constroller 通常作用在控制層,但是目前該功能與 @Component 相同。
通過在類上使用 @Repository、@Component、@Service 和 @Constroller 注解,Spring會自動創建相應的 BeanDefinition 對象,並注冊到 ApplicationContext 中。這些類就成了 Spring受管組件。這三個注解除了作用於不同軟件層次的類,其使用方式與 @Repository 是完全相同的。
另外,除了上面的四個注解外,用戶可以創建自定義的注解,然后在注解上標注 @Component,那么,該自定義注解便具有了與所@Component 相同的功能。不過這個功能並不常用。
當一個 Bean 被自動檢測到時,會根據那個掃描器的 BeanNameGenerator 策略生成它的 bean名稱。默認情況下,對於包含 name 屬性的 @Component、@Repository、 @Service 和@Controller,會把 name 取值作為 Bean 的名字。如果這個注解不包含 name值或是其他被自定義過濾器發現的組件,默認 Bean 名稱會是小寫開頭的非限定類名。如果你不想使用默認 bean命名策略,可以提供一個自定義的命名策略。首先實現 BeanNameGenerator接口,確認包含了一個默認的無參數構造方法。然后在配置掃描器時提供一個全限定類名,如下所示:
<beans ...> <context:component-scan base-package="a.b" name-generator="a.SimpleNameGenerator"/> </beans>
與通過 XML 配置的 Spring Bean 一樣,通過上述注解標識的Bean,其默認作用域是"singleton",為了配合這四個注解,在標注 Bean 的同時能夠指定 Bean 的作用域,Spring2.5 引入了 @Scope 注解。使用該注解時只需提供作用域的名稱就行了,如下所示:
@Scope("prototype") @Repository public class Demo { … }
如果你想提供一個自定義的作用域解析策略而不使用基於注解的方法,只需實現 ScopeMetadataResolver接口,確認包含一個默認的沒有參數的構造方法。然后在配置掃描器時提供全限定類名:
<context:component-scan base-package="a.b" scope-resolver="footmark.SimpleScopeResolver" />