Hibernate學習5—Hibernate操作對象2

來源:互聯網
上載者:User

標籤:new   有用   技術分享   update   teacher   ima   是否一致   value   test   

第二節:Session 常用方法講解                                        2)load和get()方法:資料庫中不存在與OID 對應的記錄,Load()方法會拋出異常:load方法預設採用消極式載入,load出來的對象是一個代理類。開始並沒有值,只有用到它的屬性等的時候,才會去發出sql語句。而get方法一開始就發出sql語句。 如果說擷取一個對象是為了刪除它,可以用load,因為只要擷取個引用就行了。如果說擷取一個對象是為了訪問它的屬性,建議用get;
@Test    public void testLoadClass() {        Class c = (Class) session.load(Class.class, Long.valueOf(2));    //class id為2的不存在,拋出異常        System.out.println(c.getStudents());    }        @Test    public void testGetClass() {        Class c = (Class) session.get(Class.class, Long.valueOf(2));    //class id為2的不存在,列印null        System.out.println(c);    }
View Code

 

2)update:

@Test    public void testUpdateClass(){        Session session1=sessionFactory.openSession();        session1.beginTransaction();        Class c=(Class)session1.get(Class.class, Long.valueOf(1));        session1.getTransaction().commit();         session1.close();                Session session2=sessionFactory.openSession();        session2.beginTransaction();        c.setName("08電腦本科2");        session2.update(c);        session2.getTransaction().commit();        session2.close();    }
View Code

 補充:

update方法:1.更新一個detached的對象;2.更新一個transient的會報錯;但是更新自己設定id的transient對象可以(資料庫有對應記錄);3.上面的,比如更新teacher,我們只是想更新name,但是它會把所有的屬性都更新一遍;這樣會造成效率低,比如有個欄位特別長...4.持久化的對象,只要改變了它的內容,session在提交或者關閉的時候,會檢查緩衝中的和資料庫中的是否一致,如果不一致,自動的發update語句;但是也和上面一樣,雖然只改了一個欄位,也會更新所有的欄位;5.能不能做到:哪個欄位改了才更新,哪個欄位沒改,哪個欄位就不更新?怎麼做:a.xml配置:<class name="com.cy.Teacher" dynamic-update="true">.....</class>b.跨session更新的問題:@Test    public void testUpdate5() {                        Session session = sessionFactory.getCurrentSession();        session.beginTransaction();        Student s = (Student)session.get(Student.class, 1);        s.setName("zhangsan5");        session.getTransaction().commit();                s.setName("z4");                Session session2 = sessionFactory.getCurrentSession();        session2.beginTransaction();        session2.update(s);        session2.getTransaction().commit();    }首先student對象被我們放到了緩衝裡,s.setName("zhangsan3"),Hibernate會檢查哪些屬性改過了,這時候產生sql語句,由於使用了dynamic-update,它就只更新name這個欄位了;session提交之後,關閉了。緩衝中的這個對象沒了。但是記憶體中Student s這個對象還在,是detached狀態的。這個對象又setName("z4"),第二個session2來了,這個session2裡面沒有s這個對象,然後update(s),它有沒有地方來比較哪個欄位改過了?沒有,它沒法將記憶體中的s和session2緩衝中的s來比較,所以update(s),發出的sql會更新全部的欄位;c.根據上面,如果想跨session,只更新改過的欄位,怎麼做:將上面的update改為merge:@Test    public void testUpdate6() {                        Session session = sessionFactory.getCurrentSession();        session.beginTransaction();        Student s = (Student)session.get(Student.class, 1);        s.setName("zhangsan6");        session.getTransaction().commit();                s.setName("z4");                Session session2 = sessionFactory.getCurrentSession();        session2.beginTransaction();        session2.merge(s);        session2.getTransaction().commit();    }merge:把這個對象給我合并到資料庫;原來沒改的內容還需要合并嗎?不需要。merge的時候,它怎麼檢查哪些欄位改過哪些欄位沒改過呢?緩衝中又沒有,只能從資料庫中load一次,所以它在update之前先發出了一條select語句,然後再比較你給我的對象和我load的對象在什麼地方不同,再重新發update語句。d:dynamic-update這種xml配置,對應的JPA Annotation沒有對應的屬性;在真正開發中建議使用HQL:session.createQuery("update Student s set s.name=‘z5‘ where s.id = 1");@Test    public void testUpdate7() {        Session session = sessionFactory.getCurrentSession();        session.beginTransaction();        Query q = session.createQuery("update Student s set s.name=‘z5‘ where s.id = 1");        q.executeUpdate();        session.getTransaction().commit();            }

 

3)saveOrUpdate:

saveOrUpdate(): 如果傳的是一個臨時對象,則執行save方法;如果傳的是游離對象,就調用update方法;
@Test    public void testSaveOrUpdateClass(){        Session session1=sessionFactory.openSession();        session1.beginTransaction();        Class c=(Class)session1.get(Class.class, Long.valueOf(1));        session1.getTransaction().commit();        session1.close();                Session session2=sessionFactory.openSession();        session2.beginTransaction();        c.setName("08電腦本科3");                Class c2=new Class();        c2.setName("09電腦本科3");        session2.saveOrUpdate(c);        //c是游離狀態,執行update        session2.saveOrUpdate(c2);        //c2臨時狀態,執行save        session2.getTransaction().commit();        session2.close();                /**         * 發出的sql:         *     Hibernate: select class0_.classId as classId1_0_0_, class0_.className as classNam2_0_0_ from t_class class0_ where class0_.classId=?            Hibernate: insert into t_class (className) values (?)            Hibernate: update t_class set className=? where classId=?         */    }
View Code

 

4)merge:

有的時候update會報錯:session中有兩個對象,擁有相同的OID(比如OID為1),更新的時候,session發現緩衝中你已經有一個OID為1的對象了,所以更新的時候就報錯了;比如:
@Test    public void testUpdateClass2(){        Session session1=sessionFactory.openSession();        session1.beginTransaction();        Class c=(Class)session1.get(Class.class, Long.valueOf(1));        session1.getTransaction().commit();        session1.close();                Session session2=sessionFactory.openSession();        session2.beginTransaction();        Class c2=(Class)session2.get(Class.class, Long.valueOf(1));        c.setName("08電腦本科3");                session2.update(c);        session2.getTransaction().commit();        session2.close();    }     
View Code

執行報錯:

 

為瞭解決這個問題,多了個merge方法,合并對象:更新的時候如果發現這個對象OID和session緩衝中另一個對象OID重合了,調用merge方法就會合并,把這兩個對象的屬性合并,然後更新;
@Test    public void testMergeClass(){        Session session1=sessionFactory.openSession();        session1.beginTransaction();        Class c=(Class)session1.get(Class.class, Long.valueOf(1));        session1.getTransaction().commit();         session1.close();                Session session2=sessionFactory.openSession();        session2.beginTransaction();                Class c2=(Class)session2.get(Class.class, Long.valueOf(1));        c.setName("08電腦本科4");            session2.merge(c);        session2.getTransaction().commit();         session2.close();    }
View Code

 

5)delete:

@Test    public void testDeleteStudent(){        Student student=(Student)session.load(Student.class, Long.valueOf(1));        session.delete(student);        session.getTransaction().commit();            session.close();    }
View Code

 因為刪除的時候,只需要獲得它的引用,這裡使用了load消極式載入就行了。不需要使用get了,因為不需要擷取它裡面的屬性。

session.delete的時候還沒有真正刪除,提交事務的時候,才同步資料庫,真的刪了。

  

Hibernate學習5—Hibernate操作對象2

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.