亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入解析Java的Hibernate框架中的持久對(duì)象

 更新時(shí)間:2016年07月06日 09:00:21   作者:zhang_xinxiu  
Hibernate的持久對(duì)象在數(shù)據(jù)庫數(shù)據(jù)操作中有著重要作用,這里我們就來深入解析Java的Hibernate框架中的持久對(duì)象,首先必須從理解持久化對(duì)象的生命周期開始:

一、持久對(duì)象生命周期
應(yīng)用程序在使用Hibernate框架后,創(chuàng)建的持久對(duì)象會(huì)經(jīng)歷一整套生命周期來完成數(shù)據(jù)庫的操作,其中主要的三個(gè)狀態(tài)分別是瞬態(tài)(Transient)、持久化(Persistent)、脫管(detached)。這三種狀態(tài)的轉(zhuǎn)換是能夠在應(yīng)用程序中控制的,如下圖:

20167690714503.png (511×312)

為了能清楚的了解這幾種狀態(tài),這里使用一個(gè)實(shí)例來查看下這幾種狀態(tài)下對(duì)象的不同,下面狀態(tài)內(nèi)的代碼,具體步驟如下:
(1)創(chuàng)建Hibernate_session程序集,并添加像相應(yīng)的jar包;
(2)配置Hibernate,添加相應(yīng)的實(shí)體User類,及它的映射文件,并配置好相應(yīng)的數(shù)據(jù)庫連接;
User類文件的映射文件User.hbm.xml代碼:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- Generated 2014-4-30 15:39:33 by Hibernate Tools 3.4.0.CR1 --> 
<hibernate-mapping> 
 <class name="com.hibernate.User"> 
  <id name="id"> 
   <generator class="uuid"/> 
  </id> 
  <property name="name"/> 
  <property name="password"/> 
  <property name="createTime"/> 
  <property name="expireTime"/> 
 </class> 
</hibernate-mapping> 

Hibernate數(shù)據(jù)庫連接配置代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
 <session-factory> 
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_session</property> 
  <property name="hibernate.connection.username">root</property> 
  <property name="hibernate.connection.password">ab12</property> 
  <!-- dialect:方言,封裝的底層API,類似于Runtime,將數(shù)據(jù)庫轉(zhuǎn)換為配置中的相應(yīng)的語言 --> 
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
   
  <mapping resource="com/hibernate/User.hbm.xml"/> 
 </session-factory> 
</hibernate-configuration>

(3)添加靜態(tài)成員sessionfactory的公共類,用來創(chuàng)建一個(gè)SessionFactory及其Session對(duì)象;

package com.hibernate; 
 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 
 
public class session { 
  
 private static SessionFactory factory; //聲明靜態(tài)局部變量SessionFactory,數(shù)據(jù)庫鏡像 
  
 static{ 
  try{ 
   //創(chuàng)建并獲取配置數(shù)據(jù)庫的配置文件,默認(rèn)獲取hibernate.cfg.xml 
   Configuration cfg=new Configuration().configure(); 
   factory=cfg.buildSessionFactory(); //構(gòu)建一個(gè)數(shù)據(jù)庫鏡像 
  }catch(Exception e){ 
   e.printStackTrace(); //打印錯(cuò)誤信息 
  }   
 } 
  
 public static Session getSession(){ 
  return factory.openSession(); //返回創(chuàng)建的session對(duì)象 
 } 
  
 public static SessionFactory getSessionFactory(){ 
  return factory; //返回相應(yīng)的SessionFactory 
 } 
  
 //關(guān)閉session對(duì)象 
 public static void closeSession(Session session){ 
  if(session != null){ 
   if(session.isOpen()){ 
    session.close(); 
   } 
  } 
 } 
} 

(4)添加一個(gè)Source Folder,并在該文件夾內(nèi)添加名稱為com.hibernate的package包,并在包中添加一個(gè)名稱為SessionTest的類文件。

package com.hibernate; 
 
import java.util.Date; 
 
import junit.framework.TestCase; 
 
import org.hibernate.Session; 
import org.hibernate.Transaction; 
 
public class SessionTest extends TestCase { 
 
} 

二、狀態(tài)轉(zhuǎn)化方法
1、對(duì)象直接進(jìn)入Persistent狀態(tài)    
     
1.1 get方法
從數(shù)據(jù)庫中獲取一行信息,并將該信息同步到創(chuàng)建的對(duì)象中,該方法返回一個(gè)Object對(duì)象,如果沒有查詢到內(nèi)容則返回null。下面的實(shí)例通過采用Session的get方法來獲取一個(gè)對(duì)象,并將對(duì)象轉(zhuǎn)換為實(shí)例。

public void testGet1(){ 
 Session session=null; 
 Transaction tx = null; 
 try{ 
  session=HibernateUtils.getSession(); 
  //開啟事務(wù) 
  tx= session.beginTransaction(); 
  //get加載上來的對(duì)象為持久對(duì)象 
  //執(zhí)行g(shù)et會(huì)馬上發(fā)出查詢語句,如果不存在會(huì)返回null 
  User user=(User)session.get(User.class,"ff80808145bc28cc0145bc28ce020002"); 
  System.out.println(user.getName()); 
   
  //persistent狀態(tài) 
  //persistent狀態(tài)的對(duì)象,當(dāng)對(duì)象的屬性發(fā)生改變的時(shí)候 
  //Hibernate在清理緩存(臟數(shù)據(jù)檢查)的時(shí)候,會(huì)和數(shù)據(jù)庫同步 
  user.setName("趙柳"); 
   
  session.getTransaction().commit(); 
 }catch(Exception e){ 
  e.printStackTrace(); 
  if(tx != null){ 
   tx.rollback(); 
  } 
 }finally{ 
  HibernateUtils.closeSession(session); 
 }  
} 

設(shè)置斷點(diǎn),獲取User對(duì)象。            

20167690757908.png (814×218)

獲取到了該對(duì)象,通過強(qiáng)制轉(zhuǎn)換后得到了一個(gè)user對(duì)象。程序中添加了setName方法,也就是說會(huì)更新數(shù)據(jù)庫中的名稱,執(zhí)行完成后檢查數(shù)據(jù)庫,如下圖更新結(jié)果。     

20167690817755.png (812×203)

1.2 load方法
功能類似于get方法,也是從數(shù)據(jù)庫中獲取數(shù)據(jù)并同步到對(duì)象中,該方法支持lazy是一種懶漢操作,它返回的是一個(gè)持久化的Object對(duì)象或者一個(gè)代理,所以需要進(jìn)行轉(zhuǎn)化。

public void testLoad1(){ 
 Session session=null; 
 try{ 
  session=HibernateUtils.getSession(); 
  //不會(huì)馬上查詢語句,因?yàn)閘oad支持lazy(延遲加載/懶加載) 
  //什么教lazy?只有真正使用這個(gè)對(duì)象的時(shí)候,再創(chuàng)建,對(duì)于Hibernate來說 
  //才真正發(fā)出查詢語句,主要為了提高性能,lazy是Hibernate中非常重要的特性 
  //Hibernate的lazy是如何實(shí)現(xiàn)的?采用代理對(duì)象實(shí)現(xiàn),代理對(duì)象主要采用的是CGLIB庫生成的 
  //而不是JDK的動(dòng)態(tài)代理,因?yàn)镴DK的動(dòng)態(tài)代理只能對(duì)實(shí)現(xiàn)了借口的類生成代理,CGLIB可以對(duì)類生成 
  //代理,它采用的是繼承方式 
  User user=(User)session.load(User.class,"8a1b653745bcc7b50145bcc7b7140001"); 
  System.out.println(user.getName()); 
   
  //persistent狀態(tài) 
  //persistent狀態(tài)的對(duì)象,當(dāng)對(duì)象的屬性發(fā)生改變的時(shí)候 
  //Hibernate在清理緩存(臟數(shù)據(jù)檢查)的時(shí)候,會(huì)和數(shù)據(jù)庫同步 
  user.setName("zhaoliu"); 
   
  session.getTransaction().commit(); 
 }catch(Exception e){ 
  e.printStackTrace(); 
 }finally{ 
  HibernateUtils.closeSession(session); 
 }  
} 

查詢獲取該User對(duì)象如下圖:

20167690836499.png (811×242)

分析上圖,獲取的User對(duì)象并不完整,或者說并沒有常見一個(gè)User對(duì)象,更是一種代理,它使用了CGLIB來預(yù)加載對(duì)象,只有在使用該對(duì)象時(shí)才真正創(chuàng)建。
1.3 Get Vs load
get和load方法很重要,在面試Hibernate時(shí)經(jīng)常會(huì)考到,下面對(duì)比下兩者。
相同點(diǎn):

(1)功能相同,將關(guān)系數(shù)據(jù)轉(zhuǎn)化為對(duì)象;
(2)使用方法相同,同樣需要制定兩個(gè)參數(shù)
不同點(diǎn):

(1)load方法支持lazy操作,預(yù)加載對(duì)象,在使用時(shí)才創(chuàng)建,get是直接將關(guān)系數(shù)據(jù)轉(zhuǎn)化為對(duì)象;
(2)load加載對(duì)象如果不存在會(huì)拋出objectNotFoundException異常,get如果沒有獲取數(shù)據(jù)會(huì)返回null。

2、手動(dòng)構(gòu)造detached對(duì)象
想要獲取對(duì)象還有另外一種方法,它區(qū)別于get與load方法,是一種手動(dòng)獲取的方法,首先常見一個(gè)對(duì)象,然后通過制定id的方式獲取該對(duì)象的數(shù)據(jù),方法如下:

public void testUer(){ 
  Session session=null; 
  try{ 
     
    session=HibernateUtils.getSession(); 
    session.beginTransaction(); 
     
    //手動(dòng)構(gòu)造detached對(duì)象 
    User user=new User(); 
    user.setId("8a1b653745bcc7b50145bcc7b7140001"); 
     
    //persistent狀態(tài) 
    //persistent狀態(tài)的對(duì)象,當(dāng)對(duì)象的屬性發(fā)生改變的時(shí)候 
    //Hibernate在清理緩存(臟數(shù)據(jù)檢查)的時(shí)候,會(huì)和數(shù)據(jù)庫同步 
    session.getTransaction().commit(); 
  }catch(Exception e){ 
    e.printStackTrace(); 
  }finally{ 
    HibernateUtils.closeSession(session); 
  }   
} 

查看獲取的結(jié)果圖:

20167690857850.png (810×212)                    

分析結(jié)果圖,代碼中使用了setId方法為該對(duì)象制定了id號(hào),在制定id號(hào)后就能夠?qū)υ搶?duì)象進(jìn)行操作,在事務(wù)提交后同步到數(shù)據(jù)庫中,采用了手動(dòng)指定,手動(dòng)指定了對(duì)象的信息。
2.1 Delete方法
刪除數(shù)據(jù)庫中指定的對(duì)象,在刪除前必須將對(duì)象轉(zhuǎn)化到Persistent狀態(tài),可以使用get、load或者手動(dòng)的方法指定對(duì)象,使用方法如下代碼:

session=HibernateUtils.getSession(); 
session.beginTransaction(); 
User user=(User)session.load(User.class,"8a1b653745bcc6d50145bcc6d67a0001"); 
//建議采用此種方式刪除,先加載再刪除 
session.delete(user); 

2.2 Update

更新數(shù)據(jù),該方法會(huì)修改數(shù)據(jù)庫中的數(shù)據(jù)。在使用的時(shí)候會(huì)出現(xiàn)量中情況,更新數(shù)據(jù)庫某個(gè)字段值或者更新數(shù)據(jù)庫的整行值
2.2.1  更新某個(gè)字段值
如果只想要更新某個(gè)字段的值,在update前,需要使用load或者get方法使對(duì)象轉(zhuǎn)化為persistent狀態(tài)代碼如下:

//獲取session對(duì)象 
session=HibernateUtils.getSession(); 
//開啟事務(wù) 
session.beginTransaction(); 
//或者可以使用另外的方法開啟 
//session.getTransaction().begin(); 
 
//加載獲取User對(duì)象 
//方法一:使用load方法 
//User user=(User)session.load(User.class, "8a1b653745bcc7b50145bcc7b7140001"); 
//方法二:手動(dòng)獲取 
User user=new User(); 
user.setId("8a1b653745bcc7b50145bcc7b7140001"); 
 
//更新姓名 
user.setName("zhangsan"); 
session.update(user); 
session.getTransaction().commit(); 

2.2.2 更新整行                       
想要更新整行的數(shù)據(jù),可以采用手動(dòng)將狀態(tài)轉(zhuǎn)換到detached狀態(tài),手動(dòng)指定對(duì)象的id值,代碼如下:

//獲取session對(duì)象 
session=HibernateUtils.getSession(); 
//開啟事務(wù) 
session.beginTransaction(); 
//或者可以使用另外的方法開啟 
//session.getTransaction().begin(); 
 
//手動(dòng)獲取 
User user=new User(); 
user.setId("8a1b653745bcc7b50145bcc7b7140001"); 
 
//更新姓名 
user.setName("zhangsan"); 
session.update(user); 
session.getTransaction().commit(); 

查看更新結(jié)果:

20167691051283.png (797×91)

分析更新結(jié)果,它其實(shí)更新了數(shù)據(jù)庫的整行數(shù)據(jù),這種更新操作有太多的不確定因素,不建議使用。

2.3 save方法

插入數(shù)據(jù)。在執(zhí)行save方法時(shí)會(huì)調(diào)用數(shù)據(jù)庫的insert語句,向數(shù)據(jù)庫中添加新的一行。save后的對(duì)象會(huì)轉(zhuǎn)化為持久態(tài),在此狀態(tài)下的對(duì)象能夠再次更新對(duì)象,在最后提交事務(wù)時(shí)會(huì)同更改更新到數(shù)據(jù)庫。如下:

public void testSave2(){ 
  Session session=null; 
  Transaction tx = null; 
  try{ 
    session=HibernateUtils.getSession(); 
    //開啟事務(wù) 
    tx= session.beginTransaction(); 
     
    //Transient狀態(tài) 
    User user=new User(); 
    user.setName("zhangsi"); 
    user.setPassword("123"); 
    user.setCreateTime(new Date()); 
    user.setExpireTime(new Date()); 
     
    //persistent狀態(tài) 
    //persistent狀態(tài)的對(duì)象,當(dāng)對(duì)象的屬性發(fā)生改變的時(shí)候 
    //Hibernate在清理緩存(臟數(shù)據(jù)檢查)的時(shí)候,會(huì)和數(shù)據(jù)庫同步 
    session.save(user); 
    user.setName("lisi"); 
     
    tx.commit(); 
     
  }catch(Exception e){ 
    e.printStackTrace(); 
    if(tx != null){ 
      tx.rollback(); 
    } 
  }finally{ 
    HibernateUtils.closeSession(session); 
  } 
   
  //detached狀態(tài) 
} 

查看上例運(yùn)行結(jié)果視圖:

20167691108747.png (997×135)

分析結(jié)果:session在提交事務(wù)的時(shí)候其實(shí)做了兩部的操作,結(jié)合代碼中的更新過程,首先是新增了一個(gè)User對(duì)象,之后執(zhí)行了save操作,它會(huì)調(diào)用insert語句,然后在代碼中做了一個(gè)setName的操作,重新修改了名稱,但這時(shí)還沒有同步到數(shù)據(jù)庫中而是在內(nèi)存中,這時(shí)就會(huì)有兩種狀態(tài),我們稱此時(shí)的數(shù)據(jù)位臟數(shù)據(jù),最后提交事務(wù)的時(shí)候更新到數(shù)據(jù)庫中。

相關(guān)文章

  • Java多線程之線程狀態(tài)詳解

    Java多線程之線程狀態(tài)詳解

    這篇文章主要介紹了Java多線程 線程狀態(tài)原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 深入了解Java atomic原子類的使用方法和原理

    深入了解Java atomic原子類的使用方法和原理

    這篇文章主要介紹了深入了解Java atomic原子類的使用方法和原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • 使用SpringMVC 重寫、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù)

    使用SpringMVC 重寫、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù)

    這篇文章主要介紹了使用SpringMVC 重寫、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中的枚舉enum詳細(xì)解讀

    Java中的枚舉enum詳細(xì)解讀

    這篇文章主要介紹了Java中的枚舉enum詳細(xì)解讀,當(dāng)我們使用enum關(guān)鍵字開發(fā)一個(gè)枚舉類時(shí),默認(rèn)會(huì)繼承Enum類,而且是一個(gè)final類,當(dāng)有多個(gè)枚舉對(duì)象時(shí),使用逗號(hào) ,隔開,最后一個(gè)用分號(hào);結(jié)尾,需要的朋友可以參考下
    2024-01-01
  • Java如何判斷線程是否結(jié)束的三種方法

    Java如何判斷線程是否結(jié)束的三種方法

    本文主要介紹了Java如何判斷線程是否結(jié)束的三種方法,主要介紹了三種方法,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java List接口與Iterator接口及foreach循環(huán)使用解析

    Java List接口與Iterator接口及foreach循環(huán)使用解析

    這篇文章主要介紹了Java List接口與Iterator接口及foreach循環(huán),主要包括List接口與Iterator接口及foreach循環(huán)具體的使用方法和代碼,需要的朋友可以參考下
    2022-04-04
  • SpringCloud基于Feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用的問題小結(jié)

    SpringCloud基于Feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用的問題小結(jié)

    這篇文章主要介紹了SpringCloud基于Feign遠(yuǎn)程調(diào)用,通過使用 Feign 的方式,我們可以更加優(yōu)雅地進(jìn)行多參數(shù)的遠(yuǎn)程調(diào)用,避免了手動(dòng)拼接URL或構(gòu)建復(fù)雜的請(qǐng)求體,需要的朋友可以參考下
    2024-02-02
  • Swift洗牌動(dòng)畫效果的實(shí)現(xiàn)方法

    Swift洗牌動(dòng)畫效果的實(shí)現(xiàn)方法

    這篇文章主要介紹了Swift洗牌動(dòng)畫效果的實(shí)現(xiàn)方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2016-12-12
  • springboot連接neo4j報(bào)錯(cuò)的解決方案

    springboot連接neo4j報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了springboot連接neo4j報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 解決mybatisPlus null 值更新的問題

    解決mybatisPlus null 值更新的問題

    這篇文章主要介紹了解決mybatisPlus null 值更新的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02

最新評(píng)論