一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 深入解析Java的Hibernate框架中的持久對象

深入解析Java的Hibernate框架中的持久對象

2020-05-24 12:34zhang_xinxiu JAVA教程

Hibernate的持久對象在數據庫數據操作中有著重要作用,這里我們就來深入解析Java的Hibernate框架中的持久對象,首先必須從理解持久化對象的生命周期開始:

一、持久對象生命周期
應用程序在使用Hibernate框架后,創建的持久對象會經歷一整套生命周期來完成數據庫的操作,其中主要的三個狀態分別是瞬態(Transient)、持久化(Persistent)、脫管(detached)。這三種狀態的轉換是能夠在應用程序中控制的,如下圖:

深入解析Java的Hibernate框架中的持久對象

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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數據庫連接配置代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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對象;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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的類文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
package com.hibernate;
 
import java.util.Date;
 
import junit.framework.TestCase;
 
import org.hibernate.Session;
import org.hibernate.Transaction;
 
public class SessionTest extends TestCase {
 
}

二、狀態轉化方法
1、對象直接進入Persistent狀態    
     
1.1 get方法
從數據庫中獲取一行信息,并將該信息同步到創建的對象中,該方法返回一個Object對象,如果沒有查詢到內容則返回null。下面的實例通過采用Session的get方法來獲取一個對象,并將對象轉換為實例。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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對象。            

深入解析Java的Hibernate框架中的持久對象

獲取到了該對象,通過強制轉換后得到了一個user對象。程序中添加了setName方法,也就是說會更新數據庫中的名稱,執行完成后檢查數據庫,如下圖更新結果。     

深入解析Java的Hibernate框架中的持久對象

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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對象如下圖:

深入解析Java的Hibernate框架中的持久對象

分析上圖,獲取的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的方式獲取該對象的數據,方法如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);
  }  
}

查看獲取的結果圖:

深入解析Java的Hibernate框架中的持久對象                    

分析結果圖,代碼中使用了setId方法為該對象制定了id號,在制定id號后就能夠對該對象進行操作,在事務提交后同步到數據庫中,采用了手動指定,手動指定了對象的信息。
2.1 Delete方法
刪除數據庫中指定的對象,在刪除前必須將對象轉化到Persistent狀態,可以使用get、load或者手動的方法指定對象,使用方法如下代碼:

?
1
2
3
4
5
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狀態代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//獲取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值,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//獲取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();

查看更新結果:

深入解析Java的Hibernate框架中的持久對象

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

2.3 save方法

插入數據。在執行save方法時會調用數據庫的insert語句,向數據庫中添加新的一行。save后的對象會轉化為持久態,在此狀態下的對象能夠再次更新對象,在最后提交事務時會同更改更新到數據庫。如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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狀態
}

查看上例運行結果視圖:

深入解析Java的Hibernate框架中的持久對象

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美一区不卡二区不卡三区 | 久久精品国产在热亚洲 | 911香蕉视频 | 久久伊人免费 | 国产第一福利影院 | 男男双性生子产乳高辣h | 古装床戏做爰无遮挡三级 | 国产综合亚洲欧美日韩一区二区 | 视频在线观看大片 | 日本免费在线 | 亚洲黄色天堂 | 久久偷拍人 | 免费一级毛片在线播放放视频 | 末代皇帝无删减版在线观看 | 国产亚洲99影院 | 2012年中文字幕在线看 | 特黄特色大片免费视频播放 | 日本免费高清在线观看播放 | 国产99视频精品免费视频7 | 国产精品久久久久jk制服 | 日本亚洲欧洲高清有码在线播放 | 色亚| 日韩高清无砖砖区2022 | 91李宗精品72集在线观看 | 亚洲一区二区福利视频 | 国产福利片在线 易阳 | 单身男女韩剧在线看 | 欧美kkk4444在线观看 | 亚洲啊v | 日本视频免费在线播放 | 日日操天天射 | 91亚洲一区二区在线观看不卡 | 草莓视频旧版本 | 调教禽兽 | 91在线视频播放 | 午夜影院0606免费 | 亚洲精品国偷拍自产在线观看蜜臀 | 欧美大美bbb和大白屁股 | 波多野结衣久久国产精品 | 特黄aa级毛片免费视频播放 | 色鬼网|