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

Hibernate 常用的數據庫操作方法

1. 前言

本節課程聊聊如何使用 Session 完成基本數據操作。通過本課程,你將學習到:

  • 如何實現查詢;
  • 如何實現保存和更新。

2. 基本數據操作方法

Session 中提供了很多方法,協助開發者快速完成基本的增加、刪除、修改、查詢(CRUD) 等基本數據操作。

2.1 查詢

Session 提供了 2 個語義很明確的查詢方法:

  • get() 方法;
  • load() 方法。

有選擇,就會有比較。但,請先不用著急區分兩者差異性,試著用用。
跑之前先學會走嗎?

查詢之前,可預先在表中多添加幾條數據!避免池塘沒魚,捕不到魚還不停懷疑自己,傷情緒。

get() 方法有很多重載,選擇其中一個方法:

public Object get(Class  clazz, Serializable id);  
  • 參數一: 指定待查詢的 PO 對象的類型;
  • 參數二: 指定一個實現 Serializable 接口的對象,充當查詢條件,一般是主鍵

編寫 get() 方法的查詢測試實例:

@Test    
public void testGet() {
    //會話對象
    Session session = sessionFactory.openSession();
    // 事務對象
    Transaction transaction = null;
    try {
        // 打開事務
        transaction = session.beginTransaction();
        //查詢學號為1的學生
        Student stu=(Student)session.get(Student.class, new Integer(1));
        assertEquals("男", stu.getStuSex());
        transaction.commit();  
    } catch (Exception e) {
        transaction.rollback(); 
    } finally {
        session.close();
    } 
}  

編寫 load() 方法的查詢測試實例:

@Test    
public void testLoad() {
    //會話對象
    Session session = sessionFactory.openSession();
    // 事務對象
    Transaction transaction = null;
    try {
        // 打開事務 
        transaction = session.beginTransaction();
        //查詢學號為1的學生
        Student stu=(Student)session.load(Student.class, new Integer(2));
        assertEquals("男", stu.getStuSex());
        transaction.commit();  
    } catch(Exception e) {
        transaction.rollback(); 
    } finally {
        session.close();
    }
}  

測試代碼和上面沒有很明顯區別,結果也沒有什么不同。

這兩個方法從測試角度暫時無法區分,但本質上還是有很大區別。

2.2 更新、刪除

添加數據的代碼前面課程中已經使用多次,現在討論更新、刪除。更新、刪除的前提條件:

  • 更新、刪除數據一定是數據庫中的數據;
  • 更新、刪除包括一個前置操作,查詢操作。

Session 提供了 public void delete(Object obj) 方法用來刪除數據。

編寫刪除測試實例,先查詢,再刪除:

@Test    
public void testDelete() {
    Session session = sessionFactory.openSession();
    Transaction transaction = null;
    try {
        transaction = session.beginTransaction();
        //查詢學號為1的學生
        Student stu=(Student)session.load(Student.class, new Integer(1)); 
        System.out.println(stu);
        session.delete(stu);
        transaction.commit();
    } catch (Exception e) {
        transaction.rollback();
    } finally {
        session.close();
    } 
}  

運行后,結果很明顯,數據庫中數據被刪除。

事務問題:

事務是一個較復雜的主題(后有專題課程),原生 JDBC 中,事務管理方式有:

  • 數據庫管理;
  • JDBC API 管理。

Hibernate 提供了 Transaction 對象,用來對事務進行管理。
默認:autoCommit=false,意思是底層 JDBC 把事務交給 Hibernate 管理。
查詢時,可以忽略事務。使用 Hibernate 進行增、刪、改時。須顯示調用 Transactioncommit()rollback() 方法。

Session 提供了 public void update(Object object) 方法用于數據更新。

編寫更新的測試代碼:

@Test    
public void testUpdate() {
    //會話對象
    Session session = sessionFactory.openSession();
    // 事務對象 
    Transaction transaction = null;
    try {
        // 打開事務
        transaction = session.beginTransaction();
        //查詢學號為1的學生
        Student stu=(Student)session.load(Student.class, new Integer(1));
        stu.setStuName("session同學");
        session.update(stu);
        transaction.commit(); 
    } catch (Exception e) {
        transaction.rollback();  
    } finally {
        session.close();
    }
}  

結果沒有什么意外,在程序中修改的數據通過 update() 方法同步到數據庫。

如果查詢 API 文檔,會發現除了這些語義上很明確的方法外,還有其它幾個方法

  • public void saveOrUpdate(Object object);
  • public Object merge(Object object);
  • public void persist(Object object);

可以使用測試方式得到基本結論,如編寫一個添加數據的實例時,使用 save、saveOrUpdate、persist 都可達到相同結果。

@Test
public void testAdd() {
    Session session = sessionFactory.openSession();
    // 事務對象
    Transaction transaction = null;
    try {
        // 打開事務
        transaction = session.beginTransaction();
        //添加新學生
        Student stu=new Student("慕課網", "男");
        //可換成saveOrUpdate方法,save方法
        session.persist(stu);
        transaction.commit();
    } catch (Exception e) {  
        transaction.rollback(); 
    } finally {
        session.close();
    } 
}  

本節課,只從語義層面做區分,其內在差異性留到后續課程中慢慢揭曉,算是留下一個懸念。

休息一下,小結一下:

  • Get()、Load()方法可用于查詢;
  • Save()可用于添加;
  • Update()可用于更新數據;
  • Delete()可用于刪除;
  • saveOrUpdate()有兩重性,沒有數據時添加數據,有數據時更新數據;
  • persist()方法可用于更新、添加數據;
  • merge()方法可用于更新、添加數據。

是不是有點上頭了,心累呀!Hibernate 不地道呀,搞出這么多方法,這是要逼得有選擇困難癥的人哭,其實每一個方法都有特定的應用場景,Hibernate 總是體貼入微的想著為開發者解決每一種開發場景的需求。

記住剛開始說的,抓住主分支(知道層面),不管細節(內部機制層面)。

2.3 保存大對象

能不能把一張圖片保存到數據庫?

答案是明確的。

真實應用場景中不會這么做。
數據庫中只會保存圖片路徑,具體的圖片文件會存儲在文件服務器中。

Hibernate 支持的大對象有:

  • Clob:文本大對象;
  • Blob:二進制數據大對象。

現在為每一個學生保存個人圖片:

  1. student 類中添加 stuPic 屬性(注意類型):
  private Blob stuPic;
  1. 編寫測試實例:
  @Test
  public void testInsertPic() {		
  	//會話對象
  	Session session = sessionFactory.openSession();
  	// 事務對象
  	Transaction transaction = null;
  	try {
          // 打開事務
          transaction = session.beginTransaction();
          //添加新學生
          Student stu=new Student("MK", "男");
          InputStream is=new FileInputStream("pic.png");
          Blob stuPic=Hibernate.getLobCreator(session).createBlob(is, is.available());
          stu.setStuPic(stuPic);
          session.merge(stu);
          transaction.commit();
  	} catch (Exception e) {
  		transaction.rollback();
  	} finally {
  		session.close();
  	}
  }

如果要保存文本大對象,則使用如下代碼:

Clob c=Hibernate.getLobCreator(session).createClob("我是中國人……");

執行結果,不出意外,數據保存成功。

不要試著把很多圖片直接保存到數據庫中,圖片的存儲與查詢會比較慢,會嚴重拖累數據庫性能。另外數據庫的體積也會變得臃腫不堪,現在可是一個以瘦為美的世界!

如何讀取數據庫中保存的圖片?
相信你一定能找到答案。

3. 總結

本節課程以體驗式的方式感受了 Session 為開發者提供的常用方法。

對于類似的操作,Hibernate 會有備選方法選擇,其內在的具體細節將在后續課程一一揭曉。

不要質疑 Hibernate 為什么要提供看似雷同的方法,真實場景中的需求要比 Hibernate 所能想到的更復雜。Hibenate 只是想以周全的態度為開發者保駕護航。

Hibernate 對開發者愛得深,細言碎語也就多?。?/p>