Hibernate(五)——面向對象查詢語言和鎖

    Hibernate作了數據庫中表和咱們實體類的映射,使咱們沒必要再編寫sql語言了。可是有時候查詢的特殊性,仍是須要咱們手動來寫查詢語句呢,Hibernate框架爲了解決這個問題給咱們提供了HQLHibernate  Query  Language面向對象的查詢語言,和QBCQuery by Criteria)徹底面向對象的查詢,這裏簡單總結一下如何是面向對象來編寫ql語句呢。 java

   一,HQLHibernate框架中的查詢語言,是一種面向對象查詢語言,和sql語句仍是很是相似的,就是將sql語句中的表改爲實體名,字段改成屬性名便可,其它基本都很類似的。主要用的是Query這個對象。返回值可使用listiterate(多值),uniqueResult(單值)等屬性進行取值。下邊看幾個小例子: node

   1,模糊查詢+list迭代: sql

String key = "san";       
Query query = session.createQuery("FROM Student s where  s.sname like ?"); //HQL語句。看裏邊都是使用類名和屬性名代替了數據庫中的表和字段  
query.setParameter(0, "%"+key+"%");  //參數索引從0開始。  
//query.setString(0, "%"+key+"%");  
List<Student> sts =  query.list();  
for(Student s : sts){  
    System.out.println(s.getSname());  
}


  2iterate至關於集合中的迭代器,Hibernate框架會先查詢符合條件的全部id值,而後根據每一個id去查詢每一條記錄,這樣咱們查詢N條件記錄時,框架幫咱們發送了N+1條語句,這也就是你們常常討論的N+1問題。這個咱們能夠經過實際的例子實驗一下: 數據庫

Query query = session.createQuery("from Student s");      
      
    Iterator<Student> it = query.iterate();  
    while(it.hasNext()){  
        Student s = (Student)it.next();  
        System.out.println(s.getSname());  
    }


  3,返回結果是一個的話,可使用uniqueResult值來獲取: 緩存

public static void testSelect(Session session){          
    Query query = session.createQuery("from Student s where s.sid=1");        
    Student s = (Student)query.uniqueResult();  
    System.out.println(s.getSname());  
}


  4,固然Query對象也支持update,delete,insert,可是這些操做會當即對數據庫的數據進行操做,而不對緩存中的數據進行操做,那麼在支持緩存時,數據可能會出現衝突,因此使用要慎用 安全

 

Query query = session.createQuery("update Student s set s.sname='張三123' where s.sid=1" ); int i = query.executeUpdate(); if(i==1){  
    System.out.println("更新成功");  
}




   5,這裏說一下二者和緩存之間的關係吧: session

    iterate方法默認是支持緩存的,只要咱們的框架配置了二級緩存的支持,iterate方法也是會支持的。 app

    list呢?默認是不支持緩存的,如何讓它支持緩存呢,這裏須要咱們的配置,這裏簡單看一下支持緩存的配置吧? 框架

    a,首先須要引入jar包和對應的xml配置文件,這裏的jar包及配置文件和二級緩存的jar包是同樣的:ehcache-1.2.3.jarehcache.xml         ide

    b,hibernate.cfg.xml中啓用查詢緩存(注意不是二級緩存):

<!--啓用查詢緩存 -->  
<propertynamepropertyname="hibernate.cache.use_query_cache">true</property>


    c,讓框架識別緩存組件,和二級緩存中是同樣的:

<!--讓框架識別ehcache緩存組件 -->  
<propertynamepropertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>


    這樣配置了之後,list就支持緩存了,此查詢緩存是支持一級查詢和二級查詢的。


  二,QBCQuery by Criteria,是經過利用Criteria對象來進行查詢的,更適合作不定參數查詢的狀況,這裏舉一個簡單例子,

Criteria cra = session.createCriteria(Student.class);  
// _ 匹配一個字符,   % 匹配多個字符  
cra.add(Restrictions.like("sname", "%s%"));  
cra.addOrder(Order.desc("sid"));  
List<Student> sts = cra.list();  
for(Student s : sts){  
    System.out.println(s.getSname());


    上邊兩項是Hibernate框架中,面向對象編寫SQL語句的寫法,整體上和sql語句的編寫是相似的,可是更加面向對象,對一些功能的編寫更加容易,咱們能夠根據不一樣狀況進行不一樣的選擇使用便可。

  三,咱們這裏來看一下Hibernate中的鎖機制吧,在此框架中鎖機制包括悲觀鎖和樂觀鎖

  1,悲觀鎖:對於一些數據咱們是不能同時去修改的,不然就會出現數據的錯誤,在數據庫中咱們能夠經過行級鎖select……for update進行對數據的鎖定,避免的。而在框架中就是經過悲觀鎖的。爲何叫它悲觀鎖呢?由於發生這種同時修改數據的概率是很是很是小,而此種鎖卻一直加上了,因此它是一種悲觀者的身份來作的事。因此稱爲悲觀鎖。看一下怎麼使用吧!

    設置LockMode.UPGRADE參數,那麼只有當前事務提交後,另外的事務纔可以查詢這個數據。這種悲觀鎖的性能比較底。

      Account account =(Account)session.get(Account.class, 1 , LockMode.UPGRADE);

  2,樂觀鎖:其實就是以樂觀人的態度來解決這種數據同時修改的問題。解決原理是,當事務不一樣時發生時,沒有鎖,若是事務同步發生了,它的鎖就起做用了。因此來講,它只是在這種概率很小的狀況發生時纔會加鎖,因此叫樂觀鎖。它的性能大大的提升了。

    a,實現方式:時間戳和版本號(Hibernate框架實現的)

    b,在咱們須要加樂觀鎖對應的數據上,添加ptimistic-lock="version"屬性:

<hibernate-mapping>  
  
    <!-- optimistic-lock="version" 使用樂觀鎖 -->  
    <class name="com.bjpowernode.hibernate.pojo.Account" table="t_account" optimistic-lock="version">  
        <id name="aid" column="aid">  
            <generator class="assigned"/>  
        </id>  
          
        <!-- 版本號字段 ,這裏須要咱們在對應的pojo類中添加對應的verget,set方法-->  
        <version name="ver" column="version"></version>  
          
        <property name="money"/>  
    </class>  
</hibernate-mapping>


  這樣,框架會自動爲咱們調用版本號,來進行樂觀鎖的的管理。功能仍是很是強大的。尤爲對於一些特別須要安全的數據,例如銀行卡的餘額等等。

  綜上,爲Hibernate中面向對象查詢語句,與鎖的簡單總結。感受Hibernate的功能仍是很是強大的,須要咱們不斷的挖掘,鑽研……

相關文章
相關標籤/搜索