国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Hibernate4.x之Session--常用方法

2019-11-14 22:01:08
字體:
來源:轉載
供稿:網友
Hibernate4.x之session--常用方法

接上篇文章繼續學習Hibernate的Session(http://m.survivalescaperooms.com/dreamfree/p/4111777.html)

持久化對象的狀態;  站在持久化的角度,Hibernate把對象分為4種狀態:持久化狀態、臨時狀態、游離狀態、刪除狀態。  Session的特定方法能使對象從一個狀態轉換到另一個狀態。

  臨時對象(Transient):    在使用代理主鍵的情況下,OID通常為null    不處于Session的緩存中    在數據庫中沒有對應的記錄  持久化對象(也叫“托管”)(Persist)    OID為null    位于Session緩存中    若在數據庫中已經有和其對應的記錄,持久化對象和數據庫中的相關記錄對應    Session在flush緩存時,會根據持久化對象的屬性變化,來同步更新數據庫    在同一個Session實例的緩存中,數據庫表中的每條記錄只對應唯一的持久化對象  刪除對象(Removed):    在數據庫中沒有和其OID對應的記錄    不再處于Session緩存中    一般情況下,應用程序不該再使用被刪除的對象  游離對象(也叫"脫管")(Detached):    OID不為null    不再處于Session緩存中    一般情況下,游離對象是由持久化對象轉變過來的,因此在數據庫中可能還存在與它對應的記錄

下面的圖片說明了Hibernate中對象狀態的轉換:

Session的save方法  Session的save()方法使一個臨時對象轉變為持久化對象  Session的save()方法完成以下操作:    把News對象加入到Session緩存中,使它進入持久化狀態    選用映射文件指定的標識符生成器,為持久化對象分配唯一的OID,在使用代理主鍵的情況下,setId()方法為News對象設置OID是無效的    計劃執行一條insert語句:在flush緩存的時候  Hibernate通過持久化對象的OID來維持它和數據庫相關記錄的對應關系。當News對象處于持久化狀態時,不允許程序隨意修改它的ID

  persist()和save()的區別:    當對一個OID不為null的對象執行save()方法時,會把該對象以一個新的OID保存到數據庫中;但執行persist()方法時會拋出一個異常Session的get()和load()方法  都可以根據給定的OID從數據庫加載一個持久化對象區別:  當數據庫中不存在與OID對應的記錄時,load()方法拋出ObjectNotFoundException異常,而get()方法返回null  兩者采用不同的延遲檢索策略:load()方法支持延遲加載策略。而get不支持Session的update()方法  Session的update()方法使一個游離對象轉變為持久化對象,并且計劃執行一條update語句  若希望Session僅當修改了News對象的屬性時,才執行update()語句,可以把映射文件中<class>元素的select-before-update設為true。該屬性的默認值為false  當update()方法關聯一個游離對象時,如果在Session的緩存中已經存在相同的OID的持久化對象,會拋出異常  當update()方法關聯一個游離對象時,如果數據庫中不存在相應的記錄,也會拋出異常Session的saveOrUpdate()方法  Session的saveOrUpdate()方法同時包含了save()與update()方法的功能

  

  

判定對象為臨時對象的標準  java對象的OID為null  映射文件中的<id>設置了unsaved-value屬性,并且Java對象的OID取值與這個unsaved-value屬性值匹配

Session的merge()方法

  

  

Session的delete()方法  Session的delete()方法既可以刪除一個游離對象,也可以刪除一個持久化對象  Session的delete()方法處理過程  計劃執行一條delete語句  把對象從Session的緩存中刪除,該對象進入刪除狀態  Hibernate的cfg.xml配置文件中有一個hibernate.use_identifier_rollback屬性,其默認值為false,若把它設為true,將改變delete()方法的運行行為:delete()方法會把持久化對象或游離對象的OID設置為null,使它們變為臨時對象通過Hibernate調用存儲過程  work接口:直接通過JDBC API來訪問數據庫的操作  Session的doWork(Work)方法用于執行Work對象指定的操作,即調用Work對象的execute()方法。Session會把當前使用的數據庫連接傳遞給execute()方法Hibernate與觸發器協同工作  Hibernate與數據庫中的觸發器協同工作時,會造成兩類問題    觸發器使Session的緩存中的持久化對象與數據庫中對應的數據不一致;觸發器運行在數據庫中,它執行的操作對Session是透明的    session的update()方法盲目地激發觸發器;無論游離對象的屬性是否發生變化,都會執行update語句,而update語句會激發數據庫中相應的觸發器解決方案:  在執行完Session的相關操作后,立即調用Session的flush()方法和refresh()方法,迫使Session的緩存與數據庫同步(refresh()方法重新從數據庫加載對象)  在映射文件的<class>元素中設置select-before-update屬性;當Session的update或saveOrUpdate()方法更新一個游離對象時,會先執行select語句,獲得當前游離對象在數據庫中的最新數據。只有在一致的情況下才會執行update語句

測試類:

  1 package com.yl.hibernate.entities;  2   3 import static org.junit.Assert.*;  4   5 import java.sql.CallableStatement;  6 import java.sql.Connection;  7 import java.sql.SQLException;  8 import java.util.Date;  9  10 import org.hibernate.Session; 11 import org.hibernate.SessionFactory; 12 import org.hibernate.Transaction; 13 import org.hibernate.cfg.Configuration; 14 import org.hibernate.jdbc.Work; 15 import org.hibernate.service.ServiceRegistry; 16 import org.hibernate.service.ServiceRegistryBuilder; 17 import org.junit.After; 18 import org.junit.Before; 19 import org.junit.Test; 20  21 public class HibernateTest { 22  23     PRivate SessionFactory sessionFactory; 24     private Session session; 25     private Transaction transaction; 26      27     @Before 28     public void init() { 29         Configuration configuration = new Configuration().configure(); 30         ServiceRegistry serviceRegistry =  31                 new ServiceRegistryBuilder().applySettings(configuration.getProperties()) 32                                             .buildServiceRegistry(); 33  34         sessionFactory = configuration.buildSessionFactory(serviceRegistry); 35          36         session = sessionFactory.openSession(); 37  38         transaction = session.beginTransaction(); 39     } 40     @After 41     public void destory() { 42         transaction.commit(); 43          44         session.close(); 45          46         sessionFactory.close(); 47     } 48      49     @Test 50     public void testSessionCache() { 51         News news = (News)session.get(News.class, 21); 52         System.out.println(news); 53         session.flush(); 54         News news2 = (News)session.get(News.class, 21); 55         System.out.println(news2); 56          57         System.out.println(news == news2);//true 58     } 59  60     /** 61      * flush:使數據庫表中的記錄和Session緩存中的對象的狀態保持一致。為了保持一致,則可能會發送對應的SQL語句。 62      *     1.在Transaction的commit()方法中:先調用session的flush方法,再提交事務 63      *  2.flush()方法可能會發送SQL語句,但不會提交事務 64      *  3.注意:在為提交事務或顯示調用session.flush()方法 之前,也有可能會flush()操作。 65      *      1).執行HQL或QBC查詢,會先進行flush操作,以得到數據表的最新紀錄 66      *      2).若記錄的ID是由底層數據庫使用自增的方式生成的,則在調用save方法時,就會立即發送INSERT語句 67      *  因為save方法后,必須保證對象的ID是存在的! 68      */ 69     @Test 70     public void testFlush2() { 71         News news = new News("Hibernate", "Oracle", new Date()); 72         session.save(news); 73     } 74      75     @Test 76     public void testFlush() { 77         /*News news = (News)session.get(News.class, 21); 78         news.setAuthor("Bruce Eckel"); 79          80         News news2 = (News)session.createCriteria(News.class).uniqueResult(); 81         System.out.println(news2);*/ 82         News news = (News)session.get(News.class, 22); 83         session.flush(); 84         System.out.println(news); 85     } 86      87     /** 88      * refresh():會強制發送SELECT 語句,以使Session緩存中對象的狀態和數據表中對應的記錄保持一致! 89      */ 90     @Test 91     public void testRefresh() { 92         News news = (News) session.get(News.class, 22); 93         System.out.println(news); 94         session.refresh(news); 95         System.out.println(news); 96     } 97      98     /** 99      * clear():清理緩存100      */101     @Test102     public void testClear() {103         News news1 = (News) session.get(News.class, 21);104         session.clear();105         News news2 = (News) session.get(News.class, 21);106     }107     108     /**109      * save()方法:110      *     1.使一個臨時對象變為持久化對象111      *     2.為對象分配ID112      *     3.在flush緩存時會發送一條insert語句113      *     4.在save方法之前的id是無效的114      *     5.持久化對象的ID是不能被修改的!115      */116     @Test117     public void testSave() {118         News news = new News();119         news.setTitle("AA");120         news.setAuthor("aa");121         news.setNewsDate(new Date());122         //news.setId(100);//不起效果123         System.out.println(news);124         //news.setId(101);//拋出異常125         session.save(news);126         System.out.println(news);127     }128     /**129      * persist():也會執行insert操作130      * 和save()的區別:131      * 在調用persist方法之前,若對象已經有ID了,則不會執行insert,而拋出異常132      */133     @Test134     public void testPsesist() {135         News news = new News();136         news.setTitle("DD");137         news.setAuthor("dd");138         news.setNewsDate(new Date());139         //news.setId(200);//拋出異常140         System.out.println(news);141         session.save(news);142         System.out.println(news);143     }144     145     /**146      * 147      */148     @Test149     public void testGet() {150         News news = (News) session.get(News.class, 21);151         System.out.println(news);152     }153     154     /**155      * get 和   load156      * 157      * 1.執行get方法,會立即加載對象。158      *        而執行load方法,若不使用該對象,則不會立即執行查詢操作,而返回一個代理對象159      * 160      *      get是立即檢索,load是延遲檢索161      * 162      * 2.load方法可能會拋出LazyInitializationException(懶加載異常):在需要初始化代理對象之前已經關閉了session163      * 164      * 3.若數據表中沒有對應的記錄,且session也沒有被關閉。同時需要使用對象時165      *         get 返回null166      *         load 若不使用該對象的任何屬性,則不會出問題;若要初始化了,拋出異常167      * 168      * 169      */170     @Test171     public void testLoad() {172         News news = (News) session.load(News.class, 21);173         System.out.println(news);174     }175     176     /**177      * update:178      * 1.若更新一個持久化對象,不需要顯式的調用update對象。因為在調用Transaction的commit方法時,會先執行session的flush方法。179      * 2.更新一個游離對象,需要顯式的調用session的update方法。可以把一個游離對象變為持久化對象180      * 181      * 需要注意的:182      * 1.無論要更新的游離對象和數據表中的記錄是否一致,都會發送update語句。183      *      如何能讓update方法不再盲目的發送update語句,在.hbm.xml文件的class節點設置select-before-update的值為true,默認為flase。但通常不需要設置該屬性184      * 185      * 2.若數據表中沒有對應的記錄,但還調用了update方法,會拋出異常186      * 187      * 3.當update()方法關聯一個游離對象時,如果在Session的緩存中已經存在相同OID的持久化對象,會拋出異常。因為在Session緩存中不能有兩個OID相同的對象188      */189     @Test190     public void testUpdate() {191         /*News news = (News) session.get(News.class, 22);192         news.setAuthor("Sun");//此時news的author字段已經更新到數據庫中,因為在執行commit語句時會先執行flush,flush將session緩存中的修改同步到數據庫中。193         */194         195         News news = (News) session.get(News.class, 22);196         transaction.commit();197         session.close();198         199         session = sessionFactory.openSession();200         transaction = session.beginTransaction();201         202         203         //news.setAuthor("Sun");204         session.update(news);205         206     }207     208     /**209      * 注意:210      * 1.若OID不為空,但數據表還沒有和其對應的記錄。會拋出一個異常。211      * 2.了解:OID值等于id的unsaved-value屬性值的對象,也被認為是一個游離對象212      */213     @Test214     public void testSaveOrUpdate() {215         News news = new News("FF", "ff", new Date());216         news.setId(41);217         session.saveOrUpdate(news);218         219     }220     221     /**222      * delete: 執行刪除操作,只要OID和數據表中一條記錄對應,就會準備執行delete操作223      * 若OID在數據表中沒有對應的記錄,則拋出異常224      * 225      * 可以通過設置一個Hibernate配置文件hibernate.use_identifier_rollback 為true,使刪除對象后,把其OID置為null226      */227     @Test228     public void testDelete() {229         /*//游離對象刪除230         News news = new News();231         news.setId(42);232         233         session.delete(news);*/234         235         //持久化對象刪除236         News news = (News) session.get(News.class, 41);237         session.delete(news);//計劃刪除,并不立即執行。在commit中的flush時執行delete238         System.out.println(news);//依然可以打印239     }240     241     /**242      * evict:從session緩存中把指定的持久化對象移除243      */244     @Test245     public void testEvict() {246         News news1 = (News) session.get(News.class, 22);247         News news2 = (News) session.get(News.class, 41);248         249         news1.setTitle("AA");250         news2.setTitle("BB");251         252         session.evict(news1);253     }254     255     /**256      * 調用存儲過程257      */258     @Test259     public void testDoWork() {260         session.doWork(new Work() {261             262             @Override263             public void execute(Connection connection) throws SQLException {264                 System.out.println(connection);265                 //調用存儲過程266                 267                 //創建存儲過程的對象  268                 CallableStatement c = connection.prepareCall("{call getsum(?,?)}");269                 270                 //給存儲過程的第一個參數設置值  271                 c.setInt(1,100);  272                  273                 //注冊存儲過程的第二個參數  274                 c.registerOutParameter(2,java.sql.Types.INTEGER);  275                  276                 //執行存儲過程  277                 c.execute();  278                 279                 connection.close();280             }281         });282     }283 }


上一篇:隨筆標題4

下一篇:java底層實現容器

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洛扎县| 澎湖县| 乳山市| 大悟县| 丹东市| 鱼台县| 永兴县| 宜黄县| 巩义市| 唐海县| 阳新县| 于田县| 普格县| 红桥区| 东丰县| 新丰县| 兴山县| 西丰县| 德令哈市| 舞阳县| 夏河县| 韶关市| 会理县| 绥棱县| 哈密市| 德庆县| 佛教| 平度市| 鹤峰县| 长宁县| 永济市| 正安县| 万盛区| 石河子市| 龙州县| 宁都县| 遂宁市| 河津市| 漳州市| 贵港市| 巧家县|