Hibernate的檢索策略
立即檢索、延遲檢索,預(yù)先抓取和批量檢索都是為了優(yōu)化加載性能而設(shè)置的策略。立即加載、延遲加載、預(yù)先抓取是同一級(jí)別的策略,因?yàn)樗鼈兪侨x一的策略。用了其中一個(gè)則另外兩個(gè)就不可用了,而且被延遲加載的對(duì)象當(dāng)最終被加載時(shí),一定是使用了立即加載的形式。如果在配置文件中設(shè)置了對(duì)某個(gè)屬性的預(yù)先抓取,則對(duì)此屬性的其他加載設(shè)置全部失效(比如還設(shè)置了延遲加載,此時(shí)失效)。批量檢索可以優(yōu)化立即檢索和延遲加載,它們可以同時(shí)使用,即批量立即加載和批量延遲加載
立即檢索 類級(jí)別的立即加載關(guān)聯(lián)對(duì)象 關(guān)聯(lián)級(jí)別的立即加載指定對(duì)象的關(guān)聯(lián)對(duì)象可以設(shè)定批量檢索數(shù)量
延時(shí)檢索 類級(jí)別的延時(shí)加載關(guān)聯(lián)對(duì)象 關(guān)聯(lián)級(jí)別的延時(shí)加載指定對(duì)象的關(guān)聯(lián)對(duì)象可以設(shè)定批量檢索數(shù)量
迫切左外連接檢索 類級(jí)別不適用關(guān)聯(lián)級(jí)別通過左外連接加載與檢索方法指定對(duì)象關(guān)聯(lián)的對(duì)象
涉及到的元素屬性
<class>和<set>的lazy 默認(rèn)是true 表示延時(shí)檢索
<many-to-one><one-to-one><set> 的 outer-join <many-to-one><one-to-one>默認(rèn)auto <set> 默認(rèn) false
<class>和<set>的batch-size默認(rèn)1 指定批量檢索的數(shù)量
' 延時(shí)檢索時(shí)會(huì)產(chǎn)生代理類
' 但是僅僅初始化了OID 其他都為null
' 只有當(dāng)訪問除ID外的屬性或者修改時(shí)才會(huì)加載數(shù)據(jù)庫的數(shù)據(jù)
' 有可能在你關(guān)閉session后仍沒有初始化對(duì)象也就沒有完整的游離對(duì)象
' 只有在session范圍內(nèi)才能被初始化
' get()方法加載的對(duì)象時(shí)實(shí)際相關(guān)數(shù)據(jù)不是代理類
一對(duì)多和多對(duì)多的檢索策略
<set> 的lazy和out-join
都為false 立即檢索
lazy為false out-join為true是迫切左外連接檢索(當(dāng)有多個(gè)<set>只允許一個(gè)用)
相反時(shí)用延時(shí)檢索策略
Hibernate的檢索方式
HQL檢索方式:
1 通過Session的createQuery()方法創(chuàng)建一個(gè)Query對(duì)象包含一HQL查詢語句
2 可以動(dòng)態(tài)綁定參數(shù)
3 可以調(diào)用list()方法返回List類型的結(jié)果
exp :
List result = session.createQuery(".......").setString("name",name).setInteger("age", 21).list();
QBC檢索方式:
1 用session的才createCriteria()方法創(chuàng)建一個(gè)Criteria對(duì)象
2 可以設(shè)定查詢的條件用Expression的一些靜態(tài)方法如Expression.like("name", "T%")
Expression.eq("age", new Integer(21)
3 可以使用方法鏈也可以調(diào)用list()方法返回List類型的結(jié)果
exp :
List result = session.createCriteria(Customer.class).add(Restrictions.like("name", "T%")).add(Restrictions.eq("age", new Integer(21)).list();
4 還可以使用QBE模板檢索方式
exp :
Customer exp = new Customer();
exp.setName("tom");
List result =session.createCriteria(Customer.class).add(Example.create(exp)).list();
SQL檢索方式:
Query query=session.createSQLQuery("..............");
由于檢索和HQL比較雜亂分別舉例說明
' 最簡(jiǎn)單的查詢
HQL
Session session=sessionFactory.openSession();
Transaction tx=null;
try
{
tx=session.beginTransaction();
List result=session.createQuery("from Customer ").list();
for(Iterator it=result.iterator(); it.hasNext();)
{
Customer c =(Customer)it.next();
System.out.println("Customer's name :" + c.getName());
System.out.println("Customer's age :" + c.getAge());
}
tx.commit();
}
catch(Exception e)
{
if(tx!=null)
{
tx.rollback();
}
throw e;
}
BQC
...
List result=session.createCriteria(Customer.class).list();
...
' 指定查詢和命名別名
HQL
...
List result=session.createQuery("from Customer as c where name=:name").setString("name", "Tom").list();
...
BQC
...
List result=session.createCriteria(Customer.class).add(Restrictions.eq("name", "Tom")).list();
...
' 對(duì)查詢結(jié)果排序
desc是降序
HQL
...
List result=session.createQuery("from Customer as c order by c.name").list();
List result=session.createQuery("from Customer as c order by c.name asc, c.age desc").list();
...
BQC
...
List result=session.createCriteria(Customer.class).addOrder(Order.asc("name")).addOrder(Order.desc("age")).list();
...
' 在指定時(shí)間范圍內(nèi)查詢結(jié)果
...
tx=session.beginTransaction();
Date beginDate=java.sql.Date.valueOf("2006-8-1");
Date endDate=java.sql.Date.valueOf("2006-9-1");
List result=session.createQuery("from Customer c where c.retime <:endTime and c.retime >=:beginTime").setTimestamp("endTime", endDate).setTimestamp("beginTime", beginDate).list();
...
' 分頁查詢
HQL
...
List result=session.createQuery("from Customer c Order by c.name asc").setFirstResult(0).setMaxResults(3).list();
...
BQC
...
List result=session.createCriteria(Customer.class).addOrder(Order.asc("name")).setFirstResult(0).setMaxResults(3).list();
...
' 檢索單個(gè)對(duì)象
uniqueResult() 方法
如果不確定返回的時(shí)單個(gè)對(duì)象先用Query和Criteria的serMaxResult(1)方法設(shè)定只返回一個(gè)對(duì)象
如果確定只返回一個(gè)對(duì)象比如from Customer c where c.id=1
' HQL的兩種綁定查詢
1
session.createQuery("from Customer c where c.name=:name and c.age=:age").setString("name", "tom").setInteger("age", 20)
2
session.createQuery("from Customer c where c.name=? and c.age=?").setString(0, "tom").setInteger(1, 20)
' 特殊綁定方法
1
setEntity() 可以綁定實(shí)體對(duì)象
session.createQuery("from Order o where o.customer=:customer").setEntity("customer", customer)
2
setParameter 綁定任意類型的參數(shù)
Query query=session.createQuery("from Order o where o.customer=:customer and o.orderNumber like: orderNumber ");
query.setParameter("customer", customer, Hibernate.entity(Customer.class));
query.setParameter("orderNumber", orderNumber, Hibernate.STRING);
3
setProperties() 與一個(gè)對(duì)象的屬性綁定
Customer customer = new Customer();
customer.setName("Tom");
customer.setAge(21);
List result=session.createQuery("from Customer c where c.name=:name and c.age=:age").setProperties(customer).list();
' 設(shè)定查詢條件
' 比較運(yùn)算大于某個(gè)條件
HQL
...
List result=session.createQuery("from Customer c where c.age>23").list();
...
BQC
...
List result=session.createCriteria(Customer.class).add(Restrictions.gt("age", new Integer(23))).list();
...
' 比較運(yùn)算不等于某個(gè)條件
HQL
...
List result=session.createQuery("from Customer c where c.age<>24").list();
...
BQC
...
List result=session.createCriteria(Customer.class).add(Restrictions.not(Restrictions.eq("age", new Integer(23)))).list();
...
' 比較運(yùn)算條件為null的某個(gè)對(duì)象
HQL
...
List result=session.createQuery("from Order o where o.customer is null").list();
...
BQC
...
List result=session.createCriteria(Order.class)
.add(Restrictions.isNull("customer")).list();
...
' 范圍運(yùn)算檢索在某個(gè)范圍內(nèi)String
HQL
...
List result=session.createQuery("from Customer c where c.name in('Tom','Mike','Jack')").list();
...
BQC
...
String[] names={"Tom", "Mike", "Jack"};
List result=session.createCriteria(Customer.class)
.add(Restrictions.in("name", names)).list();
...
' 范圍運(yùn)算檢索在某個(gè)范圍內(nèi)Integer
HQL
...
List result=session.createQuery("from Customer c where c.age between 24 and 30").list();
...
BQC
...
List result=session.createCriteria(Customer.class)
.add(Restrictions.between("age", new Integer(24), new Integer(30))).list();
...
不在某個(gè)范圍內(nèi)
HQL
...
List result=session.createQuery("from Customer c where c.age not between 24 and 30").list();
...
BQC
...
List result=session.createCriteria(Customer.class)
.add(Restrictions.not(Restrictions.between("age", new Integer(24), new Integer(30)))).list();
...
' 范圍運(yùn)算字符串通配符
以 T 開頭
HQL like 'T%'
BQC add(Restrictions.like("name","T%"))
以 T 結(jié)尾
HQL like '%T'
BQC add(Restrictions.like("name","%T"))
包含 T
HQL like '%T%'
BQC add(Restrictions.like("name","%T%"))
控制長(zhǎng)度為3
HQL like 'T_ _'
BQC add(Restrictions.like("name","T_ _"))
另外
Restrictions 還有這樣的方法like(java.lang.String propertyName, java.lang.String value, MatchMode matchMode)
有一些定義好的field 具體查看API
' 邏輯運(yùn)算檢索復(fù)雜條件
條件結(jié)合
HQL
...
List result=session.createQuery("from Customer c where c.name like 'T%' and c.name like '%m'").list();
...
BQC
...
List result=session.createCriteria(Customer.class)
.add(Restrictions.like("name", "T%")).add(Restrictions.like("name", "%m")).list();
...
邏輯與
Restriction有如下方法
or(Criterion lhs, Criterion rhs)
and(Criterion lhs, Criterion rhs
HQL
...
List result=session.createQuery("from Customer c where (c.name like 'T%' and c.name like '%m') or (c.age not between 20 and 25)").list();
...
BQC
...
List result=session.createCriteria(Customer.class).add(Restrictions.or(Restrictions.and(Restrictions.like("name", "T%"), Restrictions.like("name", "%m")), Restrictions.not(Restrictions.between("age", new Integer(20), new Integer(25))))).list();
...
' 報(bào)表查詢
from 關(guān)鍵字是必須 select group by having 用于報(bào)表查詢
投影查詢只檢索出需要的字段
HQL
...
List result=session.createQuery("select c.id, c.name, o.orderNumber from Customer c join c.orders o where o.orderNumber like 'T%'").list();
Iterator it=result.iterator();
while(it.hasNext())
{
Object[] row=(Object[])it.next();
Long id=(Long)row[0];
String name=(String)row[1];
String orderNumber=(String)row[2];
System.out.println(id+" "+name+" "+orderNumber);
}
...
這個(gè)list返回的結(jié)果是集合存放的是關(guān)系數(shù)據(jù)
也可以建立一個(gè)javabean來讓結(jié)果更清晰
...
select new ergal.CustomerRow(c.id, c.name, o.orderNumber) from Customer c join c.orders o where o.orderNumber like 'T%'
...
while(it.hasNest())
{
CustomerRow cr=(CustomerRow)it.next();
Long id=(Long)cr.getId();
......
}
' 分組查詢
查詢相同姓名的的記錄
...
List result=session.createQuery("select c.name, count(c) from Customer c group by c.name").list();
Iterator it=result.iterator();
while(it.hasNext())
{
Object[] row=(Object[])it.next();
String name=(String)row[0];
Long id=(Long)row[1];
System.out.println(id+" "+name);
}
...
統(tǒng)計(jì)訂單數(shù)目
...
List result=session.createQuery("select c.id, c.name, count(o) from Customer c join c.orders o group by c.id").list();
Iterator it=result.iterator();
while(it.hasNext())
{
Object[] row=(Object[])it.next();
Long id=(Long)row[0];
String name=(String)row[1];
Long num=(Long)row[2];
System.out.println(num+" "+name+" "+id);
}
...
統(tǒng)計(jì)每個(gè)客戶的訂單總價(jià)-右外連接
...
List result=session.createQuery("select c.id, c.name, sum(o.price) from Customer c right outer join c.orders o group by c.id").list();
Iterator it=result.iterator();
while(it.hasNext())
{
Object[] row=(Object[])it.next();
Long id=(Long)row[0];
String name=(String)row[1];
Double num=(Double)row[2];
System.out.println(num+" "+name+" "+id);
}
...
統(tǒng)計(jì)每個(gè)客戶的訂單總價(jià)-加條件訂單大于一的
...
List result=session.createQuery("select c.id, c.name, sum(o.price) from Customer c join c.orders o group by c.id having(count(o)>1)").list();
Iterator it=result.iterator();
while(it.hasNext())
{
Object[] row=(Object[])it.next();
Long id=(Long)row[0];
String name=(String)row[1];
Double num=(Double)row[2];
System.out.println(num+" "+name+" "+id);
}
...
查詢時(shí)間段
tx=session.beginTransaction();
Date beginDate=java.sql.Date.valueOf("2006-8-1");
Date endDate=java.sql.Date.valueOf("2006-9-1");
List result=session.createQuery("from Customer c where c.retime <:endTime and c.retime >=:beginTime").setTimestamp("endTime", endDate).setTimestamp("beginTime", beginDate).list();
for(Iterator it=result.iterator(); it.hasNext();)
{
Customer c =(Customer)it.next();
System.out.println("Customer's name :" + c.getName());
System.out.println("Customer's regiestertime :" + c.getRetime());
}
總的來說就是將顯示時(shí)間和數(shù)據(jù)庫的時(shí)間都進(jìn)行轉(zhuǎn)化然后進(jìn)行比較
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1191506
posted on 2007-09-16 14:52
Ke 閱讀(1687)
評(píng)論(0) 編輯 收藏 所屬分類:
hibernate