Hibernate作了數據庫中表和咱們實體類的映射,使咱們沒必要再編寫sql語言了。可是有時候查詢的特殊性,仍是須要咱們手動來寫查詢語句呢,Hibernate框架爲了解決這個問題給咱們提供了HQL(Hibernate Query Language)面向對象的查詢語言,和QBC(Query by Criteria)徹底面向對象的查詢,這裏簡單總結一下如何是面向對象來編寫ql語句呢。 java
一,HQL,Hibernate框架中的查詢語言,是一種面向對象查詢語言,和sql語句仍是很是相似的,就是將sql語句中的表改爲實體名,字段改成屬性名便可,其它基本都很類似的。主要用的是Query這個對象。返回值可使用list,iterate(多值),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()); }
2,iterate至關於集合中的迭代器,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.jar,ehcache.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就支持緩存了,此查詢緩存是支持一級查詢和二級查詢的。
二,QBC(Query 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的功能仍是很是強大的,須要咱們不斷的挖掘,鑽研……