程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻解析Java的Hibernate框架中的耐久對象

深刻解析Java的Hibernate框架中的耐久對象

編輯:關於JAVA

深刻解析Java的Hibernate框架中的耐久對象。本站提示廣大學習愛好者:(深刻解析Java的Hibernate框架中的耐久對象)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析Java的Hibernate框架中的耐久對象正文


1、耐久對象性命周期
運用法式在應用Hibernate框架後,創立的耐久對象會閱歷一整套性命周期來完成數據庫的操作,個中重要的三個狀況分離是瞬態(Transient)、耐久化(Persistent)、脫管(detached)。這三種狀況的轉換是可以或許在運用法式中掌握的,以下圖:

為了能清晰的懂得這幾種狀況,這裡應用一個實例來檢查下這幾種狀況下對象的分歧,上面狀況內的代碼,詳細步調以下:
(1)創立Hibernate_session法式集,並添加像響應的jar包;
(2)設置裝備擺設Hibernate,添加響應的實體User類,及它的映照文件,並設置裝備擺設好響應的數據庫銜接;
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數據庫銜接設置裝備擺設代碼:

<?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,將數據庫轉換為設置裝備擺設中的響應的說話 --> 
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
   
  <mapping resource="com/hibernate/User.hbm.xml"/> 
 </session-factory> 
</hibernate-configuration>

(3)添加靜態成員sessionfactory的公共類,用來創立一個SessionFactory及其Session對象;

package com.hibernate; 
 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 
 
public class session { 
  
 private static SessionFactory factory; //聲明靜態部分變量SessionFactory,數據庫鏡像 
  
 static{ 
  try{ 
   //創立並獲得設置裝備擺設數據庫的設置裝備擺設文件,默許獲得hibernate.cfg.xml 
   Configuration cfg=new Configuration().configure(); 
   factory=cfg.buildSessionFactory(); //構建一個數據庫鏡像 
  }catch(Exception e){ 
   e.printStackTrace(); //打印毛病信息 
  }   
 } 
  
 public static Session getSession(){ 
  return factory.openSession(); //前往創立的session對象 
 } 
  
 public static SessionFactory getSessionFactory(){ 
  return factory; //前往響應的SessionFactory 
 } 
  
 //封閉session對象 
 public static void closeSession(Session session){ 
  if(session != null){ 
   if(session.isOpen()){ 
    session.close(); 
   } 
  } 
 } 
} 

(4)添加一個Source Folder,並在該文件夾內添加稱號為com.hibernate的package包,並在包中添加一個稱號為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 { 
 
} 

2、狀況轉化辦法
1、對象直接進入Persistent狀況         
1.1 get辦法
從數據庫中獲得一行信息,並將該信息同步到創立的對象中,該辦法前往一個Object對象,假如沒有查詢到內容則前往null。上面的實例經由過程采取Session的get辦法來獲得一個對象,並將對象轉換為實例。

public void testGet1(){ 
 Session session=null; 
 Transaction tx = null; 
 try{ 
  session=HibernateUtils.getSession(); 
  //開啟事務 
  tx= session.beginTransaction(); 
  //get加載下去的對象為耐久對象 
  //履行get會立時收回查詢語句,假如不存在會前往null 
  User user=(User)session.get(User.class,"ff80808145bc28cc0145bc28ce020002"); 
  System.out.println(user.getName()); 
   
  //persistent狀況 
  //persistent狀況的對象,當對象的屬性產生轉變的時刻 
  //Hibernate在清算緩存(髒數據檢討)的時刻,會和數據庫同步 
  user.setName("趙柳"); 
   
  session.getTransaction().commit(); 
 }catch(Exception e){ 
  e.printStackTrace(); 
  if(tx != null){ 
   tx.rollback(); 
  } 
 }finally{ 
  HibernateUtils.closeSession(session); 
 }  
} 

設置斷點,獲得User對象。            

獲得到了該對象,經由過程強迫轉換後獲得了一個user對象。法式中添加了setName辦法,也就是說會更新數據庫中的稱號,履行完成後檢討數據庫,以下圖更新成果。     

1.2 load辦法
功效相似於get辦法,也是從數據庫中獲得數據並同步到對象中,該辦法支撐lazy是一種懶漢操作,它前往的是一個耐久化的Object對象或許一個署理,所以須要停止轉化。

public void testLoad1(){ 
 Session session=null; 
 try{ 
  session=HibernateUtils.getSession(); 
  //不會立時查詢語句,由於load支撐lazy(延遲加載/懶加載) 
  //甚麼教lazy?只要真正應用這個對象的時刻,再創立,關於Hibernate來講 
  //才真正收回查詢語句,重要為了進步機能,lazy是Hibernate中異常主要的特征 
  //Hibernate的lazy是若何完成的?采取署理對象完成,署理對象重要采取的是CGLIB庫生成的 
  //而不是JDK的靜態署理,由於JDK的靜態署理只能對完成了托言的類生成署理,CGLIB可以對類生成 
  //署理,它采取的是繼續方法 
  User user=(User)session.load(User.class,"8a1b653745bcc7b50145bcc7b7140001"); 
  System.out.println(user.getName()); 
   
  //persistent狀況 
  //persistent狀況的對象,當對象的屬性產生轉變的時刻 
  //Hibernate在清算緩存(髒數據檢討)的時刻,會和數據庫同步 
  user.setName("zhaoliu"); 
   
  session.getTransaction().commit(); 
 }catch(Exception e){ 
  e.printStackTrace(); 
 }finally{ 
  HibernateUtils.closeSession(session); 
 }  
} 

查詢獲得該User對象以下圖:

剖析上圖,獲得的User對象其實不完全,或許說並沒有罕見一個User對象,更是一種署理,它應用了CGLIB來預加載對象,只要在應用該對象時才真正創立。
1.3 Get Vs load
get和load辦法很主要,在面試Hibernate時常常會考到,上面比較下二者。
雷同點:

(1)功效雷同,將關系數據轉化為對象;
(2)應用辦法雷同,異樣須要制訂兩個參數
分歧點:

(1)load辦法支撐lazy操作,預加載對象,在應用時才創立,get是直接將關系數據轉化為對象;
(2)load加載對象假如不存在會拋出objectNotFoundException異常,get假如沒有獲得數據會前往null。

2、手動結構detached對象
想要獲得對象還有別的一種辦法,它差別於get與load辦法,是一種手動獲得的辦法,起首罕見一個對象,然後經由過程制訂id的方法獲得該對象的數據,辦法以下:

public void testUer(){ 
  Session session=null; 
  try{ 
     
    session=HibernateUtils.getSession(); 
    session.beginTransaction(); 
     
    //手動結構detached對象 
    User user=new User(); 
    user.setId("8a1b653745bcc7b50145bcc7b7140001"); 
     
    //persistent狀況 
    //persistent狀況的對象,當對象的屬性產生轉變的時刻 
    //Hibernate在清算緩存(髒數據檢討)的時刻,會和數據庫同步 
    session.getTransaction().commit(); 
  }catch(Exception e){ 
    e.printStackTrace(); 
  }finally{ 
    HibernateUtils.closeSession(session); 
  }   
} 

檢查獲得的成果圖:

                    

剖析成果圖,代碼中應用了setId辦法為該對象制訂了id號,在制訂id號後就可以夠對該對象停止操作,在事務提交後同步到數據庫中,采取了手動指定,手動指定了對象的信息。
2.1 Delete辦法
刪除數據庫中指定的對象,在刪除前必需將對象轉化到Persistent狀況,可使用get、load或許手動的辦法指定對象,應用辦法以下代碼:

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

2.2 Update

更新數據,該辦法會修正數據庫中的數據。在應用的時刻會湧現量中情形,更新數據庫某個字段值或許更新數據庫的整行值
2.2.1  更新某個字段值
假如只想要更新某個字段的值,在update前,須要應用load或許get辦法使對象轉化為persistent狀況代碼以下:

//獲得session對象 
session=HibernateUtils.getSession(); 
//開啟事務 
session.beginTransaction(); 
//或許可使用別的的辦法開啟 
//session.getTransaction().begin(); 
 
//加載獲得User對象 
//辦法一:應用load辦法 
//User user=(User)session.load(User.class, "8a1b653745bcc7b50145bcc7b7140001"); 
//辦法二:手動獲得 
User user=new User(); 
user.setId("8a1b653745bcc7b50145bcc7b7140001"); 
 
//更新姓名 
user.setName("zhangsan"); 
session.update(user); 
session.getTransaction().commit(); 

2.2.2 更新整行                       
想要更新整行的數據,可以采取手動將狀況轉換到detached狀況,手動指定對象的id值,代碼以下:

//獲得session對象 
session=HibernateUtils.getSession(); 
//開啟事務 
session.beginTransaction(); 
//或許可使用別的的辦法開啟 
//session.getTransaction().begin(); 
 
//手動獲得 
User user=new User(); 
user.setId("8a1b653745bcc7b50145bcc7b7140001"); 
 
//更新姓名 
user.setName("zhangsan"); 
session.update(user); 
session.getTransaction().commit(); 

檢查更新成果:

剖析更新成果,它其實更新了數據庫的整行數據,這類更新操作有太多的不肯定身分,不建議應用。

2.3 save辦法

拔出數據。在履行save辦法時會挪用數據庫的insert語句,向數據庫中添加新的一行。save後的對象會轉化為耐久態,在此狀況下的對象可以或許再次更新對象,在最初提交事務時會同更改更新到數據庫。以下:

public void testSave2(){ 
  Session session=null; 
  Transaction tx = null; 
  try{ 
    session=HibernateUtils.getSession(); 
    //開啟事務 
    tx= session.beginTransaction(); 
     
    //Transient狀況 
    User user=new User(); 
    user.setName("zhangsi"); 
    user.setPassword("123"); 
    user.setCreateTime(new Date()); 
    user.setExpireTime(new Date()); 
     
    //persistent狀況 
    //persistent狀況的對象,當對象的屬性產生轉變的時刻 
    //Hibernate在清算緩存(髒數據檢討)的時刻,會和數據庫同步 
    session.save(user); 
    user.setName("lisi"); 
     
    tx.commit(); 
     
  }catch(Exception e){ 
    e.printStackTrace(); 
    if(tx != null){ 
      tx.rollback(); 
    } 
  }finally{ 
    HibernateUtils.closeSession(session); 
  } 
   
  //detached狀況 
} 

檢查上例運轉成果視圖:

剖析成果:session在提交事務的時刻其實做了兩部的操作,聯合代碼中的更新進程,起首是新增了一個User對象,以後履行了save操作,它會挪用insert語句,然後在代碼中做了一個setName的操作,從新修正了稱號,但這時候還沒有同步到數據庫中而是在內存中,這時候就會有兩種狀況,我們稱此時的數據位髒數據,最初提交事務的時刻更新到數據庫中。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved