Hibernate進行數據庫查詢非常簡單
?
應用操作對象的方式來進行查詢
?
使用HQL來設置查詢條件
?
[size=large]
?
使用get方法
?
使用get方法通過持久類名和ID號查找一個對象 Stu instance = (Stu) getsession().get("com.lovo.po.Stu", id);
?
使用createQuery方法
?
使用createQuery指定查詢條件 String queryString = "from Stu as model where model."? + propertyName + "= ?"; Query queryObject = getSession().createQuery(queryString); queryObject.setParameter(0, value);
?
配置查詢條件
?
把查詢條件放置在程序之外,避免硬編碼;
?
在*.hbm.xml中使用<query>標簽, 在<![CDATE[ code]]> 中寫HQL語句
?
- ???
- <query?name= "onlyfun.caterpillar.queryUser" >??
- <![CDATA[??
- select?user.name?from?User?as?user?where?user.age?=?:age?and?user.sex?=?:sex??
- ]]>??
- </query>??
使用name屬性查找配置的查詢條件
?
- Query?query?=?session.getNamedQuery( "onlyfun.caterpillar.queryUser" );??
- query.setInteger( "age" ,? 25 );??
- query.setCharacter( "sex" ,? 'M' );??
- List?names?=?query.list();??
- }??
Hibernate語言查詢
?
Hibernate Query Language,HQL
?
完全面向對象的查詢語句
?
查詢功能非常強大
?
具備繼承、多態和關聯等特性
?
Hibernate官方推薦使用HQL進行查詢。
?
HQL
?
HQL用面向對象的方式生成SQL
?
以類和屬性來代替表和數據列
?
支持多態
?
支持各種關聯
?
減少了SQL的冗余
?
HQL支持所有的關系數據庫操作
?
連接(joins,包括Inner/outer/full joins),笛卡爾積(cartesian products)
?
投影(projection)
?
聚合(Aggregation,max, avg)和分組(group)
?
排序(Ordering)
?
子查詢(Subqueries)
?
SQL函數(SQL function calls)
?
實體查詢
?
- String?hql=”from?User?user?”;??
- List?list=session.CreateQuery(hql).list();??
執行結果是,查詢出User實體對象所對應的所有數據,而且將數據封裝成User實體對象,并且放入List中返回
?
Hibernate的實體查詢存在著對繼承關系的判定 ,查詢超類會檢索出所有超類和子類類型實體對象所對應的數據
?
與標準SQL語句相似,可以在HQL語句中使用where字
?
- from?User?user?where?user.age= 20 ;??
- from?User?user?where?user.age?between? 20 ?and? 30 ;??
- from?User?user?where?user.age?in( 20 , 30 );??
- from?User?user?where?user.name?is? null ;??
- from?User?user?where?user.name?like?‘%zx%’;??
- from?User?user?where?(user.age% 2 )= 1 ;??
- from?User?user?where?user.age= 20 ?and?user.name?like?‘%zx%’;??
實體的更新和刪除
?
Hibernate3中對更新和刪除提供靈活和更具效率的解決辦法
?
- Transaction?trans=session.beginTransaction();??
- String?hql=”update?User?user?set?user.age= 20 ?where?user.age= 18 ”;??
- Query?queryupdate=session.createQuery(hql);??
- int ?ret=queryupdate.executeUpdate();??
- trans.commit();??
類似的方式來完成delete操作
?
- Transaction?trans=session.beginTransaction();??
- String?hql=”delete?from?User?user?where?user.age= 18 ”;??
- Query?queryupdate=session.createQuery(hql);??
- int ?ret=queryupdate.executeUpdate();??
- trans.commit();??
屬性查詢
?
當只需要檢索實體對象的部分屬性所對應的數據時
?
- List?list=session.createQuery(“select?user.name?from?User?user?”).list();??
也可以一次檢索多個屬性
?
- List?list=session.createQuery(“select?user.name,user.age?from?User?user?”).list();??
實例化查詢 (動態構造實例 )
?
- List?list=session.createQuery(“select? new ?User(user.name,user.age)?from?User?user?”).list();??
注意,這時所返回的User對象,僅僅只是一個普通的Java對象而以,除了查詢結果值之外,其它的屬性值都為null(包括主鍵值id),也就是說不能通過Session對象對此對象執行持久化的更新操作,只能save()
?
分組與排序
?
Order by子句 ,可以通過asc或者desc關鍵字指定排序方式 ,默認的排序方式為asc
?
- from?User?user?order?by?user.name?asc,user.age?desc;??
Group by子句與統計查詢
?
- String?hql=”select?count(user),user.age?from?User?user?group?by?user.age?having?count(user)> 10 ?”;??
- List?list=session.createQuery(hql).list();???
標準的SQL聚集函數都可以在HQL語句中使用,比如:count(),sum(),max(),min(),avg()等
?
優化統計查詢
?
customer | |
ID? | varchar2(14) |
age? | number(10) |
name | varchar2(20) |
?
order | |
ID | varchar2(14) |
order_number | number(10) |
customer_ID | varchar2(14) |
?
- from?Customer?c?inner?join?c.orders?o?group?by?c.age;( 1 )??
- select?c.ID,c.name,c.age,o.ID,o.order_number,o.customer_ID??
- from?Customer?c?inner?join?c.orders?o?group?by?c.age;( 2 )??
語句(1)檢索的結果會返回Customer與Order持久化對象,而且它們會被置于Hibernate的Session緩存之中 ,只有事務提交后它們才會從緩存中被清除 ;
?
語句(2)返回的是關系數據而并非是持久化對象,因此它們不會占用Hibernate的Session緩存,只要在檢索之后應用程序不在訪問它們,它們所占用的內存就有可能被JVM的垃圾回收器回收,而且Hibernate不會同步對它們的修改 ;
?
盡量使用通過select語句寫出需要查詢的屬性的方式來返回關系數據,而避免使用第一種查詢方式返回持久化對象(這種方式是在有修改需求時使用比較適合),這樣可以提高運行效率并且減少內存消耗 .
?
參數綁定
?
傳統JDBC的參數綁定
?
- PrepareStatement?pre=connection.prepare(“select?*?from?User?where?user.name=?”);??
- pre.setString( 1 ,”zhao”);??
- ResultSet?rs=pre.executeQuery();??
在Hibernate中共存在4種參數綁定的方式
?
按參數名稱綁定,在語句中定義命名參數要用”:”開頭
?
- Query?query=session.createQuery(“from?User?user?where?user.name=:customername?and?user.age=:customerage”);??
- ?query.setString(“customername”,name);??
- ?query.setInteger(“customerage”,age);??
按參數位置邦定
?
- Query?query=session.createQuery(“from?User?user?where?user.name=??and?user.age?=??”);??
- ?query.setString( 0 ,name);??
- ?query.setInteger( 1 ,age);??
HQL查詢中可以通過setParameter()方法邦定任意類型的參數
?
- String?hql=”from?User?user?where?user.name=:customername?”;??
- ?Query?query=session.createQuery(hql);??
- ?query.setParameter(“customername”,name,Hibernate.STRING);??
可以用query.setParameter(“customername”,name);
?
但是對于一些類型就必須寫明映射類型,比如java.util.Date類型,因為它會對應Hibernate的多種映射類型 .比如Hibernate.DATA或者Hibernate.TIMESTAMP
?
使用setProperties()方法,將命名參數與一個對象的屬性值綁定在一起
?
- Customer?customer= new ?Customer();??
- customer.setName(“pansl”);??
- customer.setAge( 80 );??
- Query?query=session.createQuery(“from?Customer?c?where?c.name=:name?and?c.age=:age?”);??
- query.setProperties(customer);??
setProperties()方法會自動將customer對象實例的屬性值匹配到命名參數上,但是要求命名參數名稱必須要與實體對象相應的屬性同名
?
使用綁定參數的優勢
?
可以利用數據庫實施性能優化,因為對Hibernate來說在底層使用的是PrepareStatement來完成查詢,因此對于語法相同參數不同的SQL語句,可以充分利用預編譯SQL語句緩存,從而提升查詢效率
?
可以防止SQL Injection安全漏洞的產生
?
構建Criteria 查詢
?
Criteria這個接口代表對一個特定的持久化類的查詢
?
Session是用來制造Criteria實例的工廠 Criteria criteria = session.createCriteria(Mytest.class);
?
Criteria對SQL進行封裝, 讓開發人員可以用對象的方式來對數據庫進行操作
?
- Criteria?criteria?=?session.createCriteria(User. class );??
- //?查詢user所有字段 ??
- List?users?=?criteria.list();??
- Iterator?iterator?=??users.iterator();??
- System.out.println( "id?\t?name/age" );??
- while (iterator.hasNext())?{??
- ????User?user?=?(User)?iterator.next();???
- ????System.out.println(user.getId()?+??
- ??????????????????????????????? "?\t?" ?+?user.getName()?+??
- ??????????????????????????????? "/" ?+?user.getAge());??????????????
- }??
Criteria是個容器,如果想要設定查詢條件,則要使用add()方法加入Restrictions的條件限制
?
如下,查詢age大于20且小于40的數據
?
- Criteria?criteria?=?session.createCriteria(User. class );??
- criteria.add(Restrictions.gt( "age" ,? new ?Integer( 20 )));??
- criteria.add(Restrictions.lt( "age" ,? new ?Integer( 40 )));??
- List?users?=?criteria.list();??
使用邏輯組合來進行查詢
?
age等于(eq)20或(or)age為空(isNull)的條件
?
- Criteria?criteria?=?session.createCriteria(User. class );??
- criteria.add(Restrictions.or(???
- ???????????????????Restrictions.eq( "age" ,? new ?Integer( 20 )),???
- ???????????????????Restrictions.isNull( "age" )???
- ???????????????));???
- List?users?=?criteria.list();??
SQL語法作限定查詢
?
使用sqlRestriction()方法來提供SQL語法作限定查詢例如:查詢name以cater開頭的數據
?
- Criteria?criteria?=?session.createCriteria(User. class );??
- criteria.add(Restrictions.sqlRestriction(“{類名}.name?LIKE?(?) ",?" cater%",?Hibernate.STRING));??
- List?users?=?criteria.list();??
其中?將被替換為cater%
?
有多個查詢條件,如BETWEEN子句的查詢,可以如下
?
- Criteria?criteria?=?session.createCriteria(User. class );??
- Integer[?]?ages?=?{ new ?Integer( 20 ),? new ?Integer( 40 )};??
- Type[?]?types?=?{Hibernate.INTEGER,?Hibernate.INTEGER};??
- criteria.add(Restrictions.?between("age”, 20 , 30 ));??
- List?users?=?criteria.list();??
Restrictions常用限定查詢方法
?
Restrictions.eq 等于
?
Restrictions.allEq 使用Map,使用key/value進行多個等于的比對
?
Restrictions.gt 大于 >
?
Restrictions.ge 大于等于 >=
?
Restrictions.lt 小于 <
?
Restrictions.le 小于等于 <=
?
Restrictions.between 對應SQL的BETWEEN子句
?
Restrictions.like 對應SQL的LIKE子句
?
Restrictions.in 對應SQL的in子句
?
Restrictions.and and關系
?
Restrictions.or or關系
?
Restrictions.sqlRestriction SQL限定查詢
?
Criteria 高級特性
?
對查詢結果進行排序
?
- //查詢所有groupId=2的記錄? ??
- ? //并分別按照姓名(順序)和groupId(逆序)排序? ??
- ?Criteria?criteria?=?session.createCriteria(TUser. class );??
- ?criteria.add(Expression.eq( "groupId" , new ?Integer( 2 )));??
- ?criteria.addOrder(Order.asc( "name" ));??
- ?criteria.addOrder(Order.desc( "groupId" ));??
Criteria 和 DetachedCriteria
?
Criteria 是在線的,所以它是由 Hibernate Session 進行創建的
?
DetachedCriteria 是離線的,創建時無需 Session ----------------------------------------------------------------------
?
DetachedCriteria deCriteria = DetachedCriteria.forClass(QQUser.class);
?
deCriteria.add ( Expression.eq("name","木棉花"));
?
Criteria criteria = deCriteria.getExecutableCriteria(session);
?
List results = criteria.list();
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
