亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

Hibernate 使用注解做元數據

1. 前言

本節課將和大家一起講解元數據概念,通過注解的方式實現 Hibernate 操作數據庫。

這一切,會讓工作變得更加簡單、直接!!本節課程你將學習到:

  • 什么是元數據;
  • Hibernate 中有哪些注解;
  • JPA 是什么。

2. 元數據

什么是元數據

先舉一個生活中的例子:你買了一袋面粉,想用來揉幾個包子,發幾個饅頭……

可以把面粉當成原始數據,包子、饅頭是你運用你的技能加工之后的成品數據。這里的技能相當于開發者的編程能力。

但是!元數據到底是什么?。?!

買面粉的時候面粉袋上有很多說明,面粉出自何地、面粉的凈重量有多少……

這些信息對于你的加工過程有很大的參考價值。面粉的出生地讓你知道什么地方出產的面粉適合做饅頭、什么地方出產的面粉適合做面包……

凈重量能告訴你最后能生產幾個包子、幾個饅頭……如果人多,就應該多買幾袋,至少能讓你在款待客人時表現的美麗又大方。

元數據的標準概念是用來描述數據的數據!

換一句容易理解的話,面粉是數據,用來包裝面粉的面粉袋上的說明信息就是元數據。

大家知道持久化對象吧:POJO+XML。XML描述的映射信息就是用來描述學生對象數據的元數據。

3. Hibernate 中使用注解

Hibernate 中,通過元數據的方式描述映射關系,其表達語法有 2 種:

  • 其一: XML 語法;
  • 其二: 本節課程要給大家隆重推薦的是注解語法。

注解語法本質就是 Java 語法。

3.1 什么是注解

注解相當于開發者給代碼添加的注釋,對,注釋也是元數據,但注釋是開發者之間進行交流用的,編譯器和JVM都會當它不存在。

注解就不同了:

  • 告訴編譯器和 JVM 如何正確使用其所標注的數據;
  • 注解是 JAVA5.0 后推出的一種新的編程思想;
  • Java 里面可以用來和 public、static 等關鍵字一樣來修飾類名、方法名、變量名。

3.2 使用注解重構代碼

現在使用注解方式重構前面代碼,使用之前先秀出 Hiernate 中常用的幾個注解:

  • @Table:描述實體類對應的表名;
  • @Idclass:指定充當主鍵的類;
  • @Entity: 標注類是實體類;
  • @Id: 描述哪個屬性對應表中的主鍵字段;
  • @Column:指定與屬性對應的字段名;
  • @Basic:等價于沒有定義注解的屬性;
  • @Transient :屬性不被持久化。

不要指望一下記住它們,還是通過使用的過程逐步理解為上策。

友情提示:心急吃不了熱豆腐??!

修改學生類

@Entity  
public class Student {
    private Integer stuId;
    private String stuName;
    private String stuSex;
    public  Student(Integer stuId, String stuName, String stuSex) {
        super();
        this.stuId = stuId;
        this.stuName = stuName;
        this.stuSex = stuSex;
    }  
    public Student(String stuName, String stuSex) { 
        super();
        this.stuName = stuName;
        this.stuSex = stuSex;
    }         
    public Student() {
        super();
    }      
    @Id      
    public Integer  getStuId() {
        return stuId;      
    }      
    public void  setStuId(Integer stuId) {
        this.stuId = stuId;      
    }      
    public String  getStuName() { 
        return stuName;  
    }      
    public void  setStuName(String stuName) {
        this.stuName = stuName;     
    }      
    public String  getStuSex() {    
        return stuSex;      
    }      
    public void  setStuSex(String stuSex) {
        this.stuSex = stuSex; 
    } 
}  

這樣可以嗎?是的,可以啦。

用放大鏡掃描一下上面的學生類,好不容易看到 2 個注解:

  • @Entity:標注這個類是持久化類;
  • @Id:標注這個屬性是標識屬性,必須給出。

不要懷疑,對于 Hibernate 來說已經足夠,需要知道的常識是:

對于其它沒有標注任何注解的屬性,Hibernate 默認為數據庫的表中有與屬性同名的字段。

替換主配置文件

<mapping resource="com/mk/po/Student.hbm.xml" />

替換成:

<mapping class="com.mk.po.Student" />

運行測試實例

// 配置對象
Configuration  configuration = new  Configuration().configure();
// 服務注冊
ServiceRegistry  serviceRegistry =new ServiceRegistryBuilder().applySettings(configuration.getProperties())               .buildServiceRegistry();
// 會話工廠
SessionFactory  sessionFactory = configuration.buildSessionFactory(serviceRegistry);  
// 會話對象
Session  session = sessionFactory.openSession();
// 事務對象
Transaction  transaction = null;
try {
    // 打開事務
    transaction = session.beginTransaction();  
    // 添加一條學生信息
    Student  student = new Student(2, "Configuration02", "男");  
    session.save(student);
    transaction.commit();
} catch (Exception e) {
    transaction.rollback();
} finally {
    session.close();
} 
}  

測試代碼還是原來的測試代碼!只是新增了一條數據!進入 MySQL 瞧一瞧,數據如假包換的插入成功。

圖片描述

是不是感覺如春風般溫暖!對 Hibernater 的感受又增加了很多。

簡直讓人無法相信,2 個注解就映射成功。但是,這是有前提條件的:

  • 應用程序中的類名關系數據庫中的表名同名時,使用一個@Entity 注解足夠;

  • 類名和表名不一樣時,則需使用 @Table(表名)注解告訴 Hibernate;

  • 應用程序中類中的屬性名數據庫表中的字段名同名時,Hibernate自會心領意會。

    實質是沒有提供注解的屬性默認使用了@Basic 注解。

  • 如果屬性名字段名不同名時,請使用 @Column ( name=“stuName”) 注解明確告訴 Hibernate。

  • 如果類中某一個屬性本就沒有對應字段名,僅僅是方便程序中某些需求,這時需要在此屬性上加上 @Transient,讓 Hibernate 對此屬性視之不理。

3.3 注解的位置

注解說:我可不是隨便的代碼!

每一個注解都有自己位置。

  • 如同 @Entity、@Table 是類級別注解,對類做整體說明;
  • 如同 @Id、@Column、@Transient 這幾個注解是屬性、方法級別的,可對屬性或方法做說明,如下:
  @Id
  private Integer stuId;
  @Column
  private String stuName;

  @Id
  public Integer getStuId() {
      return stuId;
  }
  @Column
  public String getStuName() {
      return stuName;
  }

如上 2 種方式都可告訴 Hibernate 如何映射表中的對應字段。既然有 2 種方案,必然會有優劣之分(有比較就會有差別的哲學)。

提問時間:建議使用哪一種方式?

-------------------啟動自問自答模式----------------------

建議把注解放在屬性對應的 get 方法上。
為什么?

----------------------讓你思考0.5秒鐘------------------

時間到!公布答案。

不管是放在屬性上面還是放在 get 方法上面,Hibernate 都要使用反射機制,如果直接反射屬性,則是對 OOP 封裝特性的挑戰。

雖然使用反射可以在底層為所欲為,但作為有良知的開發者來講,則要從規范上杜絕破壞 OOP 規則的事情。
當然這只是建議!最后的選擇由你決定。

3.4 XML 還是注解

這個可沒有人能給出最終答案!俗語說得好,即使是低微如一粒塵土,也有自己的價值,XML 映射和注解映射都有自己的應用場景。

注解相對而言集中性較好,在一個類文件中,且符合 Java 語法規范,更易獲得開發者喜歡。

4. JPA

考查觀察力的時刻,請問 @Entity 注解在哪一個包中?

不是使用 Hibernate 注解嗎,還用問,肯定是在 Hibernate 相關聯的包中!

恭喜你!答錯了。

前面所使用的注解清一色都在 javax.persistence 包中,標準的 Java 包,這個包全稱 Java Persistence API(持久化API)。

奇怪了吧?這么厲害,Java 官方在推出 JDK 類庫時就為Hibernate 準備了這些注解,不是吧,難不成 Java 語言研發者能預測 Hibernate 將會橫空出世,且能成為 “網紅”(互聯網網絡上知名的軟件)提前做了擁抱 Hibernate 的準備?

NO,事情的原因是這樣子的。

Jdbc 大家都在用,且都感受到其冗余、無腦的操作流程,于是針對優化 Jdbc 操作的框架如雨后春筍(此處使用夸張修飾)。

框架的出現是好事情,但多了,就不一定是好事情,對于開發者來說因業務需求可能需要在不同規范的框架中切過來切過去,開發者的時間都浪費在框架選擇上了。

Java 官方要管一管了,于是在 J2EE5.0 后推出了 JPA 注解規范:

  • JPAJava 持久化解決方案,與 Hibernate 一樣負責把數據保存進數據庫;
  • JPA 只是一種標準、規范,而不是框架;
  • JPA 自身并沒有具體的實現,類似于Jdbc規范;
  • 旨在是規范 ORM 框架,使 ORM 框架有統一的接口、統一的用法。

一句話概之,以后不管是開發 Jdbc 框架也好,升級框架也好,請遵循JPA接口規范。

JPA是想當任我行,一統 Jdbc 框架混亂的局面。

對開發者是好事,以 Java JPA 的統一接口方式使用框架。

Hibernate 在 3.x 版本后開始支持JPA規范?。?!

老板也不用為開發者切換框架的時間付出報酬了。

5. 小結

本節課了解了元數據概念,并使用注解的方式重構了前面的代碼,完成了類似的數據插入操作。

本節課中也探討了某些注解的使用,更多注解一起期待在后面的課堂內容中再相逢。

最后和大家聊了聊 JPA,一個官方的持久化方案!值得擁有。