第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Hibernate 常用的數(shù)據(jù)庫(kù)操作方法

1. 前言

本節(jié)課程聊聊如何使用 Session 完成基本數(shù)據(jù)操作。通過(guò)本課程,你將學(xué)習(xí)到:

  • 如何實(shí)現(xiàn)查詢(xún);
  • 如何實(shí)現(xiàn)保存和更新。

2. 基本數(shù)據(jù)操作方法

Session 中提供了很多方法,協(xié)助開(kāi)發(fā)者快速完成基本的增加、刪除、修改、查詢(xún)(CRUD) 等基本數(shù)據(jù)操作。

2.1 查詢(xún)

Session 提供了 2 個(gè)語(yǔ)義很明確的查詢(xún)方法:

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

有選擇,就會(huì)有比較。但,請(qǐng)先不用著急區(qū)分兩者差異性,試著用用。
跑之前先學(xué)會(huì)走嗎?

查詢(xún)之前,可預(yù)先在表中多添加幾條數(shù)據(jù)!避免池塘沒(méi)魚(yú),捕不到魚(yú)還不停懷疑自己,傷情緒。

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

public Object get(Class  clazz, Serializable id);  
  • 參數(shù)一: 指定待查詢(xún)的 PO 對(duì)象的類(lèi)型;
  • 參數(shù)二: 指定一個(gè)實(shí)現(xiàn) Serializable 接口的對(duì)象,充當(dāng)查詢(xún)條件,一般是主鍵。

編寫(xiě) get() 方法的查詢(xún)測(cè)試實(shí)例:

@Test    
public void testGet() {
    //會(huì)話(huà)對(duì)象
    Session session = sessionFactory.openSession();
    // 事務(wù)對(duì)象
    Transaction transaction = null;
    try {
        // 打開(kāi)事務(wù)
        transaction = session.beginTransaction();
        //查詢(xún)學(xué)號(hào)為1的學(xué)生
        Student stu=(Student)session.get(Student.class, new Integer(1));
        assertEquals("男", stu.getStuSex());
        transaction.commit();  
    } catch (Exception e) {
        transaction.rollback(); 
    } finally {
        session.close();
    } 
}  

編寫(xiě) load() 方法的查詢(xún)測(cè)試實(shí)例:

@Test    
public void testLoad() {
    //會(huì)話(huà)對(duì)象
    Session session = sessionFactory.openSession();
    // 事務(wù)對(duì)象
    Transaction transaction = null;
    try {
        // 打開(kāi)事務(wù) 
        transaction = session.beginTransaction();
        //查詢(xún)學(xué)號(hào)為1的學(xué)生
        Student stu=(Student)session.load(Student.class, new Integer(2));
        assertEquals("男", stu.getStuSex());
        transaction.commit();  
    } catch(Exception e) {
        transaction.rollback(); 
    } finally {
        session.close();
    }
}  

測(cè)試代碼和上面沒(méi)有很明顯區(qū)別,結(jié)果也沒(méi)有什么不同。

這兩個(gè)方法從測(cè)試角度暫時(shí)無(wú)法區(qū)分,但本質(zhì)上還是有很大區(qū)別。

2.2 更新、刪除

添加數(shù)據(jù)的代碼前面課程中已經(jīng)使用多次,現(xiàn)在討論更新、刪除。更新、刪除的前提條件:

  • 更新、刪除數(shù)據(jù)一定是數(shù)據(jù)庫(kù)中的數(shù)據(jù);
  • 更新、刪除包括一個(gè)前置操作,查詢(xún)操作。

Session 提供了 public void delete(Object obj) 方法用來(lái)刪除數(shù)據(jù)。

編寫(xiě)刪除測(cè)試實(shí)例,先查詢(xún),再刪除:

@Test    
public void testDelete() {
    Session session = sessionFactory.openSession();
    Transaction transaction = null;
    try {
        transaction = session.beginTransaction();
        //查詢(xún)學(xué)號(hào)為1的學(xué)生
        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();
    } 
}  

運(yùn)行后,結(jié)果很明顯,數(shù)據(jù)庫(kù)中數(shù)據(jù)被刪除。

事務(wù)問(wèn)題:

事務(wù)是一個(gè)較復(fù)雜的主題(后有專(zhuān)題課程),原生 JDBC 中,事務(wù)管理方式有:

  • 數(shù)據(jù)庫(kù)管理;
  • JDBC API 管理。

Hibernate 提供了 Transaction 對(duì)象,用來(lái)對(duì)事務(wù)進(jìn)行管理。
默認(rèn):autoCommit=false,意思是底層 JDBC 把事務(wù)交給 Hibernate 管理。
查詢(xún)時(shí),可以忽略事務(wù)。使用 Hibernate 進(jìn)行增、刪、改時(shí)。須顯示調(diào)用 Transactioncommit()rollback() 方法。

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

編寫(xiě)更新的測(cè)試代碼:

@Test    
public void testUpdate() {
    //會(huì)話(huà)對(duì)象
    Session session = sessionFactory.openSession();
    // 事務(wù)對(duì)象 
    Transaction transaction = null;
    try {
        // 打開(kāi)事務(wù)
        transaction = session.beginTransaction();
        //查詢(xún)學(xué)號(hào)為1的學(xué)生
        Student stu=(Student)session.load(Student.class, new Integer(1));
        stu.setStuName("session同學(xué)");
        session.update(stu);
        transaction.commit(); 
    } catch (Exception e) {
        transaction.rollback();  
    } finally {
        session.close();
    }
}  

結(jié)果沒(méi)有什么意外,在程序中修改的數(shù)據(jù)通過(guò) update() 方法同步到數(shù)據(jù)庫(kù)。

如果查詢(xún) API 文檔,會(huì)發(fā)現(xiàn)除了這些語(yǔ)義上很明確的方法外,還有其它幾個(gè)方法

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

可以使用測(cè)試方式得到基本結(jié)論,如編寫(xiě)一個(gè)添加數(shù)據(jù)的實(shí)例時(shí),使用 save、saveOrUpdate、persist 都可達(dá)到相同結(jié)果。

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

本節(jié)課,只從語(yǔ)義層面做區(qū)分,其內(nèi)在差異性留到后續(xù)課程中慢慢揭曉,算是留下一個(gè)懸念。

休息一下,小結(jié)一下:

  • Get()、Load()方法可用于查詢(xún);
  • Save()可用于添加;
  • Update()可用于更新數(shù)據(jù);
  • Delete()可用于刪除;
  • saveOrUpdate()有兩重性,沒(méi)有數(shù)據(jù)時(shí)添加數(shù)據(jù),有數(shù)據(jù)時(shí)更新數(shù)據(jù);
  • persist()方法可用于更新、添加數(shù)據(jù);
  • merge()方法可用于更新、添加數(shù)據(jù)。

是不是有點(diǎn)上頭了,心累呀!Hibernate 不地道呀,搞出這么多方法,這是要逼得有選擇困難癥的人哭,其實(shí)每一個(gè)方法都有特定的應(yīng)用場(chǎng)景,Hibernate 總是體貼入微的想著為開(kāi)發(fā)者解決每一種開(kāi)發(fā)場(chǎng)景的需求。

記住剛開(kāi)始說(shuō)的,抓住主分支(知道層面),不管細(xì)節(jié)(內(nèi)部機(jī)制層面)。

2.3 保存大對(duì)象

能不能把一張圖片保存到數(shù)據(jù)庫(kù)?

答案是明確的。

真實(shí)應(yīng)用場(chǎng)景中不會(huì)這么做。
數(shù)據(jù)庫(kù)中只會(huì)保存圖片路徑,具體的圖片文件會(huì)存儲(chǔ)在文件服務(wù)器中。

Hibernate 支持的大對(duì)象有:

  • Clob:文本大對(duì)象;
  • Blob:二進(jìn)制數(shù)據(jù)大對(duì)象。

現(xiàn)在為每一個(gè)學(xué)生保存?zhèn)€人圖片:

  1. student 類(lèi)中添加 stuPic 屬性(注意類(lèi)型):
  private Blob stuPic;
  1. 編寫(xiě)測(cè)試實(shí)例:
  @Test
  public void testInsertPic() {		
  	//會(huì)話(huà)對(duì)象
  	Session session = sessionFactory.openSession();
  	// 事務(wù)對(duì)象
  	Transaction transaction = null;
  	try {
          // 打開(kāi)事務(wù)
          transaction = session.beginTransaction();
          //添加新學(xué)生
          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();
  	}
  }

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

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

執(zhí)行結(jié)果,不出意外,數(shù)據(jù)保存成功。

不要試著把很多圖片直接保存到數(shù)據(jù)庫(kù)中,圖片的存儲(chǔ)與查詢(xún)會(huì)比較慢,會(huì)嚴(yán)重拖累數(shù)據(jù)庫(kù)性能。另外數(shù)據(jù)庫(kù)的體積也會(huì)變得臃腫不堪,現(xiàn)在可是一個(gè)以瘦為美的世界!

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

3. 總結(jié)

本節(jié)課程以體驗(yàn)式的方式感受了 Session 為開(kāi)發(fā)者提供的常用方法。

對(duì)于類(lèi)似的操作,Hibernate 會(huì)有備選方法選擇,其內(nèi)在的具體細(xì)節(jié)將在后續(xù)課程一一揭曉。

不要質(zhì)疑 Hibernate 為什么要提供看似雷同的方法,真實(shí)場(chǎng)景中的需求要比 Hibernate 所能想到的更復(fù)雜。Hibenate 只是想以周全的態(tài)度為開(kāi)發(fā)者保駕護(hù)航。

Hibernate 對(duì)開(kāi)發(fā)者愛(ài)得深,細(xì)言碎語(yǔ)也就多?。?/p>