Hibernate核心介面,hibernate核心

來源:互聯網
上載者:User

Hibernate核心介面,hibernate核心

Configuration(AnnotationConfiguration)

作用:進行配置資訊的管理

目標:用來產生SessionFactory

可以在configure方法中指定hibernate設定檔,預設(不指定)時在classpath下載入hibernate.cfg.xml檔案

載入預設的hibernate的設定檔

sessionFactory factory =new AnnotationConfiguration().configure().buildSessionFactory();

載入指定hibernate的設定檔

sessionFactory factory  = newnnotationConfiguration().configure("hibernate.xml").buildSessionFactory();


SessionFactory

作用:主要用於產生Session的工廠(資料庫連接池)

當它產生一個Session時,會從資料庫連接池取出一個串連,交給這個Session

Session session= sessionFactory.getCurrentSession();

       並且可以通過這個Session取出這個串連

getCurrentSession():表示當前環境沒有Session時,則建立一個,否則不用建立

openSession():表示建立一個Session(3.0以後不常用),使用後需要關閉這個Session

兩方法的區別:

①、openSession永遠是每次都開啟一個新的Session,而getCurrentSession不是,是從上下文找、只有當前沒有Session時,才建立一個新的Session

②、OpenSession需要手動close,getCurrentSession不需要手動close,事務提交自動close

③、getCurrentSession界定事務邊界

所指的上下文是指hibernate設定檔(hibernate.cfg.xml)中的“current_session_context_class”所指的值:(可取值:jta|thread|managed|custom.Class)

<propertyname="current_session_context_class">thread</property>

常用的是:

①、thread:是從上下文找、只有當前沒有Session時,才建立一個新的Session,主要從資料界定事務

②、jta:主要從分布式界定事務,運行時需要Application Server來支援(Tomcat不支援)

③、managed:不常用

④、custom.Class:不常用


Session

save()

session.save(Object)

session的save方法是向資料庫中儲存一個對象,這個方法產生對象的三種狀態

delete()

session.delete(Object)

Object對象需要有ID

對象刪除後,對象狀態為Transistent狀態

load()

格式: Session.load(Classarg0,Serializable arg1) throws HibernateException

    arg0:需要載入對象的類,例如:User.class

    arg1:查詢條件(實現了序列化介面的對象)。如果是數值類類型,則hibernate會自動使用封裝類,

    此方法傳回型別為Object,但返回的是代理對象。

    執行此方法時不會立即發出查詢SQL語句。只有在使用對象時,它才發出查詢SQL語句,載入對象。

    因為load方法實現了lazy(稱為消極式載入、賴載入)

    消極式載入:只有真正使用這個對象的時候,才載入(才發出SQL語句)

    hibernate消極式載入實現原理是代理方式。

    採用load()方法載入資料,如果資料庫中沒有相應的記錄,則會拋出異常對象不找到(org.hibernate.ObjectNotFoundException)

Get()    

格式:Session.get(Classarg0,Serializable arg1)方法

 arg0:需要載入對象的類,例如:User.class

 arg1:查詢條件(實現了序列化介面的對象):如果是基數類型,則hibernate會自動轉換成封裝類

 返回值:此方法傳回型別為Object,也就是對象,再強行轉換為需要載入的對象就可以了。

 如果資料不存在,則返回null;

 註:執行此方法時立即發出查詢SQL語句。

load()與get()區別

①不存在對應記錄時表現不一樣;

② load返回的是代理對象,等到真正使用對象的內容時才發出sql語句,這樣就要求在第一次使用對象時,要求session處於open狀態,否則出錯

③get直接從資料庫載入,不會消極式載入

get()和load()只根據主鍵查詢,不能根據其它欄位查詢,如果想根據非主鍵查詢,可以使用HQL

update()

①用來更新detached對象,更新完成後轉為為persistent狀態(預設更新全部欄位)

②更新transient對象會報錯(沒有ID)

③更新自己設定ID的transient對象可以(預設更新全部欄位)

④persistent狀態的對象,只要設定欄位不同的值,在session提交時,會自動更新(預設更新全部欄位)

⑤更新部分更新的欄位(更改了哪個欄位就更新哪個欄位的內容)

a)方法1:update/updatable屬性

xml:設定<property>標籤的update屬性,設定在更新時是否參與更新

<property name="name" update="false"/>

注意:update可取值為true(預設):參與更新;false:更新時不參與更新

annotateon:設定@Column的updatable屬性值,true參與更新,false:不參與更新

@Column(updatable=false)

public StringgetTitle(){return title;}

注意:此種方法很少用,因為它不靈活

b)方法2:dynamic-update屬性

注意:此方法目前只適合xml方式,JAP1.0annotation沒有對應的

在實體類的對應檔中的<class>標籤中,使用dynamic-update屬性,true:表示修改了哪個欄位就更新哪個欄位,其它欄位不更新,但要求是同一個session(不能跨session),如果跨了session同樣會更新所有的欄位內容。

<class name="com.bjsxt.Student" dynamic-update="true">

          代碼:

@Test  public void testUpdate5() {         Session session =sessionFactory.getCurrentSession();      session.beginTransaction();      Student s=(Student)session.get(Student.class, 1);      s.setName("zhangsan5");      //提交時,會只更新name欄位,因為此時的s為persistent狀態      session.getTransaction().commit();      s.setName("z4");      Session session2 =sessionFactory.getCurrentSession();      session2.beginTransaction();      //更新時,會更新所有的欄位,因為此時的s不是persistent狀態      session2.update(s);      session2.getTransaction().commit(); }

如果需要跨session實現更新修改的部分欄位,需要使用session.merget()方法,合并欄位內容

@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();}

這樣雖然可以實現部分欄位更新,但這樣會多出一條select語句,因為在欄位資料合併時,需要比較欄位內容是否已變化,就需要從資料庫中取出這條記錄進行比較

c)使用HQL(EJBQL)物件導向的查詢語言(建議)

  @Test  public void testUpdate7() {         Session session =sessionFactory.getCurrentSession();      session.beginTransaction();      Query q =session.createQuery("updateStudent s sets.name='z5' where s.id = 1");      q.executeUpdate();      session.getTransaction().commit();      } 

saveOrUpdate()

在執行的時候hibernate會檢查,如果對象在資料庫中已經有對應的記錄(是指主鍵),則會更新update,否則會添加資料save

clear()

清除session緩衝

無論是load還是get,都會首先尋找緩衝(一級緩衝,也叫session級緩衝),如果沒有,才會去資料庫尋找,調用clear()方法可以強制清除session緩衝

    Session session=sessionFactory.getCurrentSession();    session.beginTransaction();    Teacher t =(Teacher)session.load(Teacher.class,1);    System.out.println(t.getName());          session.clear();          Teacher t2=(Teacher)session.load(Teacher.class, 1);    System.out.println(t2.getName());    session.getTransaction().commit();

注意:這樣就會發出兩條SELECT語句,如果把session.clear()去除,則只會發出一條SELECT語句,因為第二次load時,是使用session緩衝中ID為1的對象,而這個對象已經在第一次load到緩衝中了。

flush()

在hibernate中也存在flush這個功能,在預設的情況下session.commit()之前時,其實執行了一個flush命令。

Session.flush功能:

清理緩衝;

執行sql(確定是執行SQL語句(確定產生update、insert、delete語句等),然後執行SQL語句。)

Session在什麼情況下執行flush:

①預設在事務提交時執行;

注意:flush時,可以自己設定,使用session.setFlushMode(FlushMode)來指定。

  session.setFlushMode(FlushMode);

FlushMode的枚舉值:

l     FlushMode.ALWAYS:任務一條SQL語句,都會flush一次

l     FlushMode.AUTO  :自動flush(預設)

l     FlushMode.COMMIT: 只有在commit時才flush

l     FlushMode.MANUAL:手動flush。

l    FlushMode.NEVER :永遠不flush  此選項在效能最佳化時可能用,比如session取資料為唯讀時用,這樣就不需要與資料庫同步了

注意:設定flush模式時,需要在session開啟事務之前設定。

②可以顯式的調用flush;

③在執行查詢前,如:iterate.

註:如果主鍵建置原則是uuid等不是由資料庫產生的,則session.save()時並不會發出SQL語句,只有flush時才會發出SQL語句,但如果主鍵建置原則是native由資料庫產生的,則session.save的同時就發出SQL語句。

evict()

例如:session.evict(user)

作用:從session緩衝(EntityEntries屬性)中逐出該對象

但是與commit同時使用,會拋出異常

session =HibernateUtils.getSession();tx =session.beginTransaction();  User1 user = newUser1();user.setName("李四");user.setPassword("123");user.setCreateTime(newDate());user.setExpireTime(newDate());          //利用Hibernate將實體類對象儲存到資料庫中,因為user主鍵建置原則採用的是uuid,所以調用完成save後,只是將user納入session的管理,不會發出insert語句,但是id已經產生,session中的existsInDatabase狀態為falsesession.save(user);              session.evict(user);//從session緩衝(EntityEntries屬性)中逐出該對象//無法成功提交,因為hibernate在清理緩衝時,在session的臨時集合(insertions)中取出user對象進行insert操作後需要更新entityEntries屬性中的existsInDatabase為true,而我們採用evict已經將user從session中逐出了,所以找不到相關資料,無法更新,拋出異常。          tx.commit();解決在逐出session緩衝中的對象不拋出異常的方法:在session.evict()之前進行顯示的調用session.flush()方法就可以了。session.save(user);              //flush後hibernate會清理緩衝,會將user對象儲存到資料庫中,將session中的insertions中的user對象清除,並且會設定session中的existsInDatabase狀態為falsesession.flush();          session.evict(user);//從session緩衝(EntityEntries屬性)中逐出該對象          //可以成功提交,因為hibernate在清理緩衝時,在Session的insertions中集合中無法找到user對象所以不會發出insert語句,也不會更新session中existsInDatabase的狀態。tx.commit();


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.