Hibernate進(jìn)行數(shù)據(jù)庫(kù)查詢非常簡(jiǎn)單
?
應(yīng)用操作對(duì)象的方式來進(jìn)行查詢
?
使用HQL來設(shè)置查詢條件
?
[size=large]
?
使用get方法
?
使用get方法通過持久類名和ID號(hào)查找一個(gè)對(duì)象 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>標(biāo)簽, 在<![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
?
完全面向?qū)ο蟮牟樵冋Z句
?
查詢功能非常強(qiáng)大
?
具備繼承、多態(tài)和關(guān)聯(lián)等特性
?
Hibernate官方推薦使用HQL進(jìn)行查詢。
?
HQL
?
HQL用面向?qū)ο蟮姆绞缴蒘QL
?
以類和屬性來代替表和數(shù)據(jù)列
?
支持多態(tài)
?
支持各種關(guān)聯(lián)
?
減少了SQL的冗余
?
HQL支持所有的關(guān)系數(shù)據(jù)庫(kù)操作
?
連接(joins,包括Inner/outer/full joins),笛卡爾積(cartesian products)
?
投影(projection)
?
聚合(Aggregation,max, avg)和分組(group)
?
排序(Ordering)
?
子查詢(Subqueries)
?
SQL函數(shù)(SQL function calls)
?
實(shí)體查詢
?
- String?hql=”from?User?user?”;??
- List?list=session.CreateQuery(hql).list();??
執(zhí)行結(jié)果是,查詢出User實(shí)體對(duì)象所對(duì)應(yīng)的所有數(shù)據(jù),而且將數(shù)據(jù)封裝成User實(shí)體對(duì)象,并且放入List中返回
?
Hibernate的實(shí)體查詢存在著對(duì)繼承關(guān)系的判定 ,查詢超類會(huì)檢索出所有超類和子類類型實(shí)體對(duì)象所對(duì)應(yīng)的數(shù)據(jù)
?
與標(biāo)準(zhǔn)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%’;??
實(shí)體的更新和刪除
?
Hibernate3中對(duì)更新和刪除提供靈活和更具效率的解決辦法
?
- 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();??
屬性查詢
?
當(dāng)只需要檢索實(shí)體對(duì)象的部分屬性所對(duì)應(yīng)的數(shù)據(jù)時(shí)
?
- List?list=session.createQuery(“select?user.name?from?User?user?”).list();??
也可以一次檢索多個(gè)屬性
?
- List?list=session.createQuery(“select?user.name,user.age?from?User?user?”).list();??
實(shí)例化查詢 (動(dòng)態(tài)構(gòu)造實(shí)例 )
?
- List?list=session.createQuery(“select? new ?User(user.name,user.age)?from?User?user?”).list();??
注意,這時(shí)所返回的User對(duì)象,僅僅只是一個(gè)普通的Java對(duì)象而以,除了查詢結(jié)果值之外,其它的屬性值都為null(包括主鍵值id),也就是說不能通過Session對(duì)象對(duì)此對(duì)象執(zhí)行持久化的更新操作,只能save()
?
分組與排序
?
Order by子句 ,可以通過asc或者desc關(guān)鍵字指定排序方式 ,默認(rèn)的排序方式為asc
?
- from?User?user?order?by?user.name?asc,user.age?desc;??
Group by子句與統(tǒng)計(jì)查詢
?
- String?hql=”select?count(user),user.age?from?User?user?group?by?user.age?having?count(user)> 10 ?”;??
- List?list=session.createQuery(hql).list();???
標(biāo)準(zhǔn)的SQL聚集函數(shù)都可以在HQL語句中使用,比如:count(),sum(),max(),min(),avg()等
?
優(yōu)化統(tǒng)計(jì)查詢
?
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)檢索的結(jié)果會(huì)返回Customer與Order持久化對(duì)象,而且它們會(huì)被置于Hibernate的Session緩存之中 ,只有事務(wù)提交后它們才會(huì)從緩存中被清除 ;
?
語句(2)返回的是關(guān)系數(shù)據(jù)而并非是持久化對(duì)象,因此它們不會(huì)占用Hibernate的Session緩存,只要在檢索之后應(yīng)用程序不在訪問它們,它們所占用的內(nèi)存就有可能被JVM的垃圾回收器回收,而且Hibernate不會(huì)同步對(duì)它們的修改 ;
?
盡量使用通過select語句寫出需要查詢的屬性的方式來返回關(guān)系數(shù)據(jù),而避免使用第一種查詢方式返回持久化對(duì)象(這種方式是在有修改需求時(shí)使用比較適合),這樣可以提高運(yùn)行效率并且減少內(nèi)存消耗 .
?
參數(shù)綁定
?
傳統(tǒng)JDBC的參數(shù)綁定
?
- PrepareStatement?pre=connection.prepare(“select?*?from?User?where?user.name=?”);??
- pre.setString( 1 ,”zhao”);??
- ResultSet?rs=pre.executeQuery();??
在Hibernate中共存在4種參數(shù)綁定的方式
?
按參數(shù)名稱綁定,在語句中定義命名參數(shù)要用”:”開頭
?
- Query?query=session.createQuery(“from?User?user?where?user.name=:customername?and?user.age=:customerage”);??
- ?query.setString(“customername”,name);??
- ?query.setInteger(“customerage”,age);??
按參數(shù)位置邦定
?
- Query?query=session.createQuery(“from?User?user?where?user.name=??and?user.age?=??”);??
- ?query.setString( 0 ,name);??
- ?query.setInteger( 1 ,age);??
HQL查詢中可以通過setParameter()方法邦定任意類型的參數(shù)
?
- String?hql=”from?User?user?where?user.name=:customername?”;??
- ?Query?query=session.createQuery(hql);??
- ?query.setParameter(“customername”,name,Hibernate.STRING);??
可以用query.setParameter(“customername”,name);
?
但是對(duì)于一些類型就必須寫明映射類型,比如java.util.Date類型,因?yàn)樗鼤?huì)對(duì)應(yīng)Hibernate的多種映射類型 .比如Hibernate.DATA或者Hibernate.TIMESTAMP
?
使用setProperties()方法,將命名參數(shù)與一個(gè)對(duì)象的屬性值綁定在一起
?
- 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()方法會(huì)自動(dòng)將customer對(duì)象實(shí)例的屬性值匹配到命名參數(shù)上,但是要求命名參數(shù)名稱必須要與實(shí)體對(duì)象相應(yīng)的屬性同名
?
使用綁定參數(shù)的優(yōu)勢(shì)
?
可以利用數(shù)據(jù)庫(kù)實(shí)施性能優(yōu)化,因?yàn)閷?duì)Hibernate來說在底層使用的是PrepareStatement來完成查詢,因此對(duì)于語法相同參數(shù)不同的SQL語句,可以充分利用預(yù)編譯SQL語句緩存,從而提升查詢效率
?
可以防止SQL Injection安全漏洞的產(chǎn)生
?
構(gòu)建Criteria 查詢
?
Criteria這個(gè)接口代表對(duì)一個(gè)特定的持久化類的查詢
?
Session是用來制造Criteria實(shí)例的工廠 Criteria criteria = session.createCriteria(Mytest.class);
?
Criteria對(duì)SQL進(jìn)行封裝, 讓開發(fā)人員可以用對(duì)象的方式來對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作
?
- 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是個(gè)容器,如果想要設(shè)定查詢條件,則要使用add()方法加入Restrictions的條件限制
?
如下,查詢age大于20且小于40的數(shù)據(jù)
?
- 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();??
使用邏輯組合來進(jìn)行查詢
?
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開頭的數(shù)據(jù)
?
- Criteria?criteria?=?session.createCriteria(User. class );??
- criteria.add(Restrictions.sqlRestriction(“{類名}.name?LIKE?(?) ",?" cater%",?Hibernate.STRING));??
- List?users?=?criteria.list();??
其中?將被替換為cater%
?
有多個(gè)查詢條件,如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進(jìn)行多個(gè)等于的比對(duì)
?
Restrictions.gt 大于 >
?
Restrictions.ge 大于等于 >=
?
Restrictions.lt 小于 <
?
Restrictions.le 小于等于 <=
?
Restrictions.between 對(duì)應(yīng)SQL的BETWEEN子句
?
Restrictions.like 對(duì)應(yīng)SQL的LIKE子句
?
Restrictions.in 對(duì)應(yīng)SQL的in子句
?
Restrictions.and and關(guān)系
?
Restrictions.or or關(guān)系
?
Restrictions.sqlRestriction SQL限定查詢
?
Criteria 高級(jí)特性
?
對(duì)查詢結(jié)果進(jìn)行排序
?
- //查詢所有g(shù)roupId=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 進(jìn)行創(chuàng)建的
?
DetachedCriteria 是離線的,創(chuàng)建時(shí)無需 Session ----------------------------------------------------------------------
?
DetachedCriteria deCriteria = DetachedCriteria.forClass(QQUser.class);
?
deCriteria.add ( Expression.eq("name","木棉花"));
?
Criteria criteria = deCriteria.getExecutableCriteria(session);
?
List results = criteria.list();
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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