hibernate学习(4)
Hibernate查詢方式
1 對(duì)象導(dǎo)航查詢
(1)根據(jù)id查詢某個(gè)客戶,再查詢這個(gè)客戶里面所有的聯(lián)系人
2 OID查詢
(1)根據(jù)id查詢某一條記錄,返回對(duì)象
3 hql查詢
(1)Query對(duì)象,寫hql語句實(shí)現(xiàn)查詢
4 QBC查詢
(1)Criteria對(duì)象
5 本地sql查詢
(1)SQLQuery對(duì)象,使用普通sql實(shí)現(xiàn)查詢
重點(diǎn)掌握前四種方式。
?
對(duì)象導(dǎo)航查詢
1 查詢某個(gè)客戶里面所有聯(lián)系人過程,使用對(duì)象導(dǎo)航實(shí)現(xiàn)
2 代碼
//根據(jù)cid=1客戶,再查詢這個(gè)客戶里面所有聯(lián)系人Customer customer = session.get(Customer.class, 1);//再查詢這個(gè)客戶里面所有聯(lián)系人//直接得到客戶里面聯(lián)系人的set集合Set<LinkMan> linkman = customer.getSetLinkMan();System.out.println(linkman.size());OID查詢
1 根據(jù)id查詢記錄
(1)調(diào)用session里面的get方法實(shí)現(xiàn)
//根據(jù)cid=1客戶,再查詢這個(gè)客戶里面所有聯(lián)系人 Customer customer = session.get(Customer.class, 1);HQL查詢
1 hql:hibernate query language,hibernate提供一種查詢語言,hql語言和普通sql很相似,最大的區(qū)別是:普通sql操作數(shù)據(jù)庫表和字段,hql操作實(shí)體類和屬性。
2 常用hql語句
(1)查詢所有:from 實(shí)體類名稱
(2)條件查詢:from 實(shí)體類名稱 where 屬性名稱=?
(3)排序查詢:from 實(shí)體類名稱 order by 實(shí)體類屬性名稱 asc/desc
3 使用hql查詢操作的時(shí)候,使用Query對(duì)象
(1)創(chuàng)建Query對(duì)象,寫hql語句
(2)調(diào)用query對(duì)象里面的方法得到結(jié)果
查詢所有
1 查詢所有客戶記錄
(1)創(chuàng)建Query對(duì)象,寫hql語句
(2)調(diào)用query對(duì)象里面的方法得到結(jié)果
2 查詢所有:from實(shí)體類名稱
//1 創(chuàng)建query對(duì)象Query query = session.createQuery("from Customer");//2 調(diào)用方法得到結(jié)果List<Customer> list = query.list();條件查詢
1 hql條件查詢語句寫法
(1)from 實(shí)體類名稱 where 實(shí)體類名稱=?and 實(shí)體類屬性名稱=?
from 實(shí)體類名稱 where 實(shí)體類屬性名稱 like ?
2 代碼
使用的方法是:
query.setParameter(arg0, arg1); // 1 創(chuàng)建query對(duì)象// select * from t_customer where cid=? and custName=?Query query = session.createQuery("from Customer where cid=? and custName=?");// 2 設(shè)置條件值// 向?里面設(shè)置值// setParameter方法兩個(gè)參數(shù)// 第一個(gè)參數(shù):int類型是?位置,?位置從0開始// 第二個(gè)參數(shù):具體參數(shù)值// 設(shè)置第一個(gè)參數(shù)值?和preparedstatement不一樣的是,它是從0開始的query.setParameter(0, 4);// 設(shè)置第二個(gè)?值query.setParameter(1, "baidu");// 3 調(diào)用方法的到結(jié)果List<Customer> list = query.list();模糊查詢
// 1 創(chuàng)建query對(duì)象// select * from t_customer where cid=? and custName=?Query query = session.createQuery("from Customer where cid=? and custName like ?");//2 設(shè)置?的值//_na %na%query.setParameter(0, 2);query.setParameter(1, "%in%");//3 調(diào)用方法得到結(jié)果List<Customer> list = query.list();hibernate底層sql代碼
Hibernate: selectcustomer0_.cid as cid1_0_,customer0_.custName as custName2_0_,customer0_.custLevel as custLeve3_0_,customer0_.custSource as custSour4_0_,customer0_.custPhone as custPhon5_0_,customer0_.custMobile as custMobi6_0_ fromt_customer customer0_ wherecustomer0_.cid=? and (customer0_.custName like ?)排序查詢
1 hql排序語句寫法
(1)from 實(shí)體類名稱 order by 實(shí)體類屬性名稱 asc/desc
// 1 創(chuàng)建query對(duì)象Query query = session.createQuery("from Customer order by cid asc");//2 調(diào)用方法得到結(jié)果List<Customer> list = query.list();分頁查詢
1 mysql實(shí)現(xiàn)分頁
(1)使用關(guān)鍵字limit實(shí)現(xiàn)
select * from t_customer limit 0,2;
第一個(gè)參數(shù)是開始位置,第二個(gè)參數(shù)是每頁顯示幾條記錄。
2 在hql中實(shí)現(xiàn)分頁
(1)在hql操作中,在語句里面不能寫limit(這是MySQL特有,Hibernate不認(rèn)識(shí)),hibernate的Query對(duì)象封裝兩個(gè)方法實(shí)現(xiàn)分頁操作。
// 1 創(chuàng)建query對(duì)象Query query = session.createQuery("from Customer");// 2 設(shè)置分頁數(shù)據(jù)// 2.1 設(shè)置開始位置query.setFirstResult(0);// 2.2 設(shè)置每頁記錄數(shù)query.setMaxResults(2);// 3 調(diào)用方法得到結(jié)果List<Customer> list = query.list();投影查詢
1 投影查詢:查詢不是所有字段的值,而是部分字段的值
select customerName from t_customer
2 投影查詢hql語句寫法:
(1)select 實(shí)體類屬性名稱 1,實(shí)體類屬性名稱 2 from 實(shí)體類名稱
(2)select 后面不能寫*。
//創(chuàng)建query對(duì)象 Query query = session.createQuery("select custName from Customer");//2 調(diào)用方法得到結(jié)果 List<Object> list = query.list();聚集函數(shù)使用?
?1 常用的聚集函數(shù)
(1)count、sum、avg、max、min
select count(*) from t_customer;
2 hql聚集函數(shù)語句寫法
(1)查詢表記錄數(shù)據(jù)
-select count(*) from?
// 1 創(chuàng)建query對(duì)象Query query = session.createQuery("select count(*) from Customer");// 2 調(diào)用方法得到結(jié)果// query對(duì)象里面有方法,直接返回對(duì)象形式Object obj = query.uniqueResult();// 返回int類型// int count = (int)obj;// 首先把object變成Long類型,再變成int類型Long lobj = (Long) obj;int count = lobj.intValue();QBC查詢
1 使用hql查詢需要寫hql語句實(shí)現(xiàn),但是使用qbc時(shí)候,不需要寫語句了,使用方法實(shí)現(xiàn)。
2 使用qbc時(shí)候,操作實(shí)現(xiàn)類和屬性
3 使用qbc,使用Criteria對(duì)象實(shí)現(xiàn)
查詢所有
1 創(chuàng)建Criteria對(duì)象
2 調(diào)用方法實(shí)現(xiàn)功能
// 1 創(chuàng)建query對(duì)象Criteria criteria = session.createCriteria(Customer.class);// 2 調(diào)用方法得到結(jié)果List<Customer> list = criteria.list();條件查詢
// 1 創(chuàng)建query對(duì)象Criteria criteria = session.createCriteria(Customer.class);//2 使用Criteria對(duì)象里面的方法設(shè)置條件值//首先使用add方法,表示設(shè)置條件值//在add方法里面使用類的方法實(shí)現(xiàn)條件設(shè)置//類似于cid=?criteria.add(Restrictions.eq("cid",4));criteria.add(Restrictions.eq("custName", "baidu"));//3 調(diào)用方法得到結(jié)果List<Customer> list = criteria.list();支持模糊查詢
criteria.add(Restrictions.like("custName", "%ai%"));排序查詢
// 1 創(chuàng)建query對(duì)象Criteria criteria = session.createCriteria(Customer.class);//設(shè)置對(duì)哪個(gè)屬性進(jìn)行排序,設(shè)置排序規(guī)則criteria.addOrder(Order.asc("cid"));List<Customer> list = criteria.list();分頁查詢
//2 設(shè)置分頁數(shù)據(jù)//2.1設(shè)置開始位置criteria.setFirstResult(1);//2.2 每頁顯示criteria.setMaxResults(2);開始位置有一個(gè)計(jì)算公式:(當(dāng)前頁-1)*每頁記錄數(shù)
?統(tǒng)計(jì)查詢
// 1 創(chuàng)建query對(duì)象Criteria criteria = session.createCriteria(Customer.class);//2 設(shè)置操作 criteria.setProjection(Projections.rowCount());//3 調(diào)用方法得到結(jié)果Object obj = criteria.uniqueResult();Long lobj = (Long)obj;int count = lobj.intValue();離線查詢
1 servlet調(diào)用service,service調(diào)用dao
(1)在dao里面對(duì)數(shù)據(jù)庫crud操作
(2)在dao里面使用hibernate框架,使用hibernate框架時(shí)候,調(diào)用session里面的方法實(shí)現(xiàn)功能
// 1 創(chuàng)建query對(duì)象// Criteria criteria = session.createCriteria(Customer.class);DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);// 2 最終執(zhí)行時(shí)候才需要sessionCriteria criteria = detachedCriteria.getExecutableCriteria(session);List<Customer> list = criteria.list();(3)在后面ssh練習(xí)中具體應(yīng)用
HQL多表查詢
Mysql里面多表查詢
1 內(nèi)連接
2 左外連接
3 右外連接
HQL實(shí)現(xiàn)多表查詢
Hql多表查詢
(1)內(nèi)連接
(2)左外連接
(3)右外連接
(4)迫切內(nèi)連接
(5)迫切左外連接
HQL內(nèi)連接
1 內(nèi)連接查詢hql語句寫法:以客戶和聯(lián)系人為例
(1)from Customer c inner join c.setLinkMan
// 1 創(chuàng)建query對(duì)象Query query = session.createQuery("from Customer c inner join c.setLinkMan");List list = query.list();返回list,list里面每部分是數(shù)組形式
2 演示迫切內(nèi)連接?
(1)迫切內(nèi)連接和內(nèi)連接底層實(shí)現(xiàn)一樣的
(2)區(qū)別:使用內(nèi)連接返回list中每部分是數(shù)組,迫切內(nèi)連接返回list每部分是對(duì)象
(3)hql語句寫法:
-from Customer c inner join fetch c.setLinkMan
HQL左外連接
1 左外連接hql語句
(1)from Customer c left outer join c.setLinkMan
(2)迫切左外連接 from Customer c left outer join fetch c.setLinkMan
2 左外連接返回list中每部分是數(shù)組,迫切左外連接返回list每部分是對(duì)象
?
?
Query query = session.createQuery("from Customer c left outer join fetch c.setLinkMan");Hibernate檢索策略
檢索策略的概念
1 hibernate檢索策略分為兩類:
(1)立即查詢,根據(jù)id查詢,調(diào)用get方法,一調(diào)用get方法馬上發(fā)送語句查詢數(shù)據(jù)庫
//根據(jù)cid=1客戶//執(zhí)行g(shù)et方法之后,是否發(fā)送sql語句//調(diào)用get方法馬上去查詢數(shù)據(jù)庫Customer customer = session.get(Customer.class, 1);(2)延遲查詢,根據(jù)id查詢,還有l(wèi)oad方法,調(diào)用load方法不會(huì)馬上發(fā)送語句查詢數(shù)據(jù),只有得到對(duì)象里面的值的時(shí)候才發(fā)送語句查詢數(shù)據(jù)庫。
Customer customer = session.load(Customer.class, 2);System.out.println(customer.getCid());System.out.println(customer.getCustName());2 延遲查詢分成兩類,
(1)類級(jí)別延遲,根據(jù)id查詢返回實(shí)體類對(duì)象,調(diào)用load方法方法不會(huì)馬上發(fā)送語句
(2)關(guān)聯(lián)級(jí)別延遲
-查詢出某個(gè)客戶,再查詢這個(gè)客戶的所有聯(lián)系人,查詢客戶的所有聯(lián)系人的過程是否需要延遲,這個(gè)過程稱為關(guān)聯(lián)級(jí)別延遲。
?
關(guān)聯(lián)級(jí)別延遲操作
1 在映射文件中進(jìn)行配置實(shí)現(xiàn)
(1)根據(jù)客戶得到所有的聯(lián)系人,在客戶映射文件中進(jìn)行配置。
?
?
2 在set標(biāo)簽上使用屬性
(1)fetch:值select
(2)lazy:值
-true:延遲
-false:不延遲
-extra:極其延遲
在LinkMan.hbm.xml文件中配置如下所示:
<set name="setLinkMan" cascade="save-update,delete" fetch="select" lazy="true">?
<set name="setLinkMan" cascade="save-update,delete" fetch="select" lazy="false">(1)調(diào)用get之后,發(fā)送兩條sql語句。
<set name="setLinkMan" cascade="save-update,delete" fetch="select" lazy="extra">極其懶惰,要什么值給什么值。
批量抓取
1 查詢所有的客戶,返回list集合,遍歷list集合,得到每個(gè)客戶,得到每個(gè)客戶的所有聯(lián)系人
?
(1)該代碼會(huì)發(fā)送多條sql語句
Criteria criteria = session.createCriteria(Customer.class);List<Customer> list = criteria.list();//得到每個(gè)客戶里面所有的聯(lián)系人for(Customer customer : list){System.out.println(customer.getCid()+" "+customer.getSetLinkMan());//每個(gè)客戶里面所有的所有聯(lián)系人Set<LinkMan> setLinkMan = customer.getSetLinkMan();for(LinkMan linkMan : setLinkMan){System.out.println(linkMan.getLkm_id()+":"+linkMan.getLkm_name());}}使用批量抓取就可以進(jìn)行優(yōu)化
2 在客戶的映射文件中,set標(biāo)簽配置
<set name="setLinkMan" batch-size="10">batch-size值越大越好,這和數(shù)據(jù)量也是有很大關(guān)系的。
導(dǎo)航查詢就是得到set集合
?
轉(zhuǎn)載于:https://www.cnblogs.com/liaoxiaolao/p/9926380.html
總結(jié)
以上是生活随笔為你收集整理的hibernate学习(4)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查询x,y之间的素数
- 下一篇: 11.9随笔