<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    石頭JAVA擺地?cái)們?/a>

    JAVA所有的討論-要一點(diǎn)一點(diǎn)的進(jìn)步

      BlogJava :: 首頁 ::  :: 聯(lián)系 ::  :: 管理 ::
      30 隨筆 :: 0 文章 :: 11 評論 :: 0 Trackbacks
    連接查詢:
       關(guān)系型數(shù)據(jù)庫之所以強(qiáng)大,其中一個原因就是可以統(tǒng)一使用表來管理同類數(shù)據(jù)信息,并且可以在相關(guān)數(shù)據(jù)之間建立關(guān)系。作為支持關(guān)系型數(shù)據(jù)庫的SQL語句來說,自然要對全面發(fā)揮這種強(qiáng)大功能提供支持,這個支持就是連接查詢。同樣作為一種關(guān)系型數(shù)據(jù)庫的持久層框架,Hibernate也對連接查詢提供了豐富的支持,在Hibernate中通過HQL與QBC兩種查詢方式都可以支持連接查詢。下面這一部分我們將通過這兩種查詢技術(shù),來詳細(xì)討論有關(guān)Hibernate對連接查詢支持的各個細(xì)節(jié)。在講解連接查詢之前,我們先來回憶一下在第一部分中講解的有關(guān)實(shí)體關(guān)聯(lián)關(guān)系的映射,在實(shí)體的配置文件中可以通過配置集合元素來指定對關(guān)聯(lián)實(shí)體的映射以及檢索策略。(請參考第一部分相關(guān)內(nèi)容)因此我們可以在實(shí)體映射配置文件中,指定關(guān)聯(lián)實(shí)體檢索策略,對關(guān)聯(lián)實(shí)體的檢索策略可以指定為“延遲檢索”,“立即檢索”,“迫切左外連接檢索”,如下所示對與Customer實(shí)體關(guān)聯(lián)的Order實(shí)體設(shè)置延遲加載:<set name=”orders” inverse=”true” lazy=”true”>,這種在實(shí)體映射配置文件中設(shè)定的檢索策略,稱為默認(rèn)檢索策略,但是這種默認(rèn)檢索策略是可以被覆蓋的,那就是在程序代碼當(dāng)中可以動態(tài)指定各種迫切檢索策略來覆蓋默認(rèn)檢索策略。
    1、    迫切左外連接查詢和左外連接查詢:
    我們看以下代碼,這段代碼將覆蓋映射文件中的檢索策略,顯示指定采用迫切左外連接查詢。
     
    HQL查詢方式:
    Query query=session.createQuery(“from Customer c left join fetch c.orders o where c.name       like ‘zhao%’ ”);
    List list=query.list();
    for(int i=0;i<list.size();i++){
     Customer customer=(Customer)list.get(i);
    }
    //QBC檢索方式:
    List list=session.createCriteria(Customer.class).setFetchMode(“orders”,FetchMode.EAGER)
            .add(Expression.like(“name”,”zhao%”,MatchMode.START).list();
    for(int i=0;i<list.size();i++){
     Customer customer=(Customer)list.get(i);
    }
    我們看到在HQL以及QBC查詢中分別通過left join fetch和FetchMode.EAGER來指定采用迫切左外連接檢索策略,當(dāng)采用了迫切左外連接檢索策略時,當(dāng)進(jìn)行檢索時即執(zhí)行查詢的list()方法時,將會立即初始化用來容納關(guān)聯(lián)實(shí)體的集合對象元素,如果在實(shí)體映射配置文件中對關(guān)聯(lián)實(shí)體設(shè)置了延遲加載,那么此時將會忽略延遲加載設(shè)置,而采用迫切左外連接策略,并且立即用關(guān)聯(lián)實(shí)體對象填充集合對象元素,即使用Order對象填充Customer對象的orders集合。因此這種檢索策略會馬上創(chuàng)建關(guān)聯(lián)實(shí)體對象,此時我想你一定會想到這種檢索策略會同時檢索出Customer和Order實(shí)體對象對應(yīng)的數(shù)據(jù),并且分別創(chuàng)建這兩個對象。恭喜你答對了,因此上面代碼會生成類似如下的SQL語句:
    Select * from customer c left join order o on c.id=o.id where c.name like ‘zhao%’;
    如果我們忽略了fetch關(guān)鍵字,就變成了左外連接查詢,如下面代碼:
    Query query=session.createQuery(“from Customer c left join c.orders o where c.name       like ‘zhao%’ ”);
    List list=query.list();
    for(int i=0;i<list.size();i++){
     Object[] objs=(Object[])list.get(i);
     Customer customer=(Customer) objs[0];
     order order=(Order)objs[1];
    }
    我們可以看到采用左外連接查詢返回的結(jié)果集中包含的是對象數(shù)組,對象數(shù)組中的每個元素存放了一對相互關(guān)聯(lián)的Customer對象和Order對象,而迫切左外連接會返回Customer對象,與Customer對象相關(guān)聯(lián)的Order對象存放在Customer對象的集合元素對象中,這就是迫切左外連接和左外連接查詢的其中一個區(qū)別(這兩種檢索生成的SQL語句是一樣的),另一個區(qū)別是當(dāng)使用左外連接時,對關(guān)聯(lián)對象的檢索會依照實(shí)體映射配置文件所指定的策略,而不會像迫切左外連接那樣忽略它,比如此時對Customer對象關(guān)聯(lián)的Order對象采用延遲加載,那么左外連接檢索也會使用延遲加載機(jī)制檢索Order對象。
    2、內(nèi)連接,迫切內(nèi)連接以及隱式內(nèi)連接:
     若采用迫切內(nèi)連接通過一下代碼可以實(shí)現(xiàn):
    Query query=session.createQuery(“from Customer c inner join fetch c.orders o where c.name       like ‘zhao%’ ”);
    List list=query.list();
    for(int i=0;i<list.size();i++){
     Customer customer=(Customer)list.get(i);
    }
    這段代碼將會采用迫切內(nèi)連接檢索,對集合元素的檢索策略以及返回結(jié)果集中的對象類型都采用與迫切左外連接一樣的方式,我這里就不再贅述,另外QBC查詢不支持迫切內(nèi)連接檢索。
    如果去掉fetch就是內(nèi)連接檢索,如下面代碼:
    Query query=session.createQuery(“from Customer c innerjoin c.orders o where c.name       like ‘zhao%’ ”);
    List list=query.list();
    for(int i=0;i<list.size();i++){
     Object[] objs=(Object[])list.get(i);
     Customer customer=(Customer) objs[0];
     order order=(Order)objs[1];
    }
    內(nèi)連接檢索,對集合元素的檢索策略以及返回結(jié)果集中的對象類型都采用與左外連接一樣的方式,QBC查詢也同樣支持內(nèi)連接檢索,如下代碼:
    List list=session.createCriteria(Customer.class)
    .add(Expression.like(“name”,”zhao%”,MatchMode.START))
    .createCriteria(“orders”)
    .add(Expression.like(“ordernumber”,”T”,MatchMode.START)).list();
          上面代碼等價于如下的HQL語句:
          Select c from Customer c join c.orders o where c.name like ‘zhao%’ and o.ordernummber like ‘T%’;因此可以采用下面的方式訪問結(jié)果集:
    for(int i=0;i<list.size();i++){
     Customer customer=(Customer)list.get(i);
    }
          由此可見,采用內(nèi)連接查詢時,HQL與QBC查詢有不同的默認(rèn)行為,HQL會檢索出成對的Customer和Order對象,而QBC僅會檢索出Customer對象。如果QBC查詢想檢索出成對的Customer和Order對象,可以采用如下代碼:
    List list=session.createCriteria(Customer.class)
    .createAlias(“orders”,”o”)
    .add(Expression.like(“this.name”,”zhao%”,MatchMode.START))
    .add(Expression.like(“ordernumber”,”T”,MatchMode.START))
    .returnMap()
    .list();
    for(int i=0;i<list.size();i++){
       Map map=(Map)list.get(i);
     Customer customer=(Customer)map.get(“this”);
     order order=(Order)map.get(“o”);
    }
        “o”和”this”分別是orders集合和Customer對象的別名。
        在HQL查詢中,還有一種查詢成為隱式內(nèi)連接,我們看下面的HQL語句,
          From order o where o.customer.name like ’ zhao% ’;這個語句通過o.customer.name訪問與Order對象關(guān)聯(lián)的Customer對象的name屬性,盡管沒有使用join關(guān)鍵字,其實(shí)隱式指定了采用內(nèi)連接檢索,它和下面這條HQL語句等價:
    From order o join o.customer c where c.name like ‘zhao%’;
    隱式內(nèi)連接只適用于多對一和一對一關(guān)聯(lián),不適用于一對多和多對多關(guān)聯(lián),另外QBC查詢不支持隱式內(nèi)連接檢索。
    3、右外連接檢索:
    由于fetch關(guān)鍵字只能應(yīng)用于innner join和left join,因此對于右外連接檢索而言,就不存在所謂的迫切右外連接查詢了,使用右外連接見如下代碼:
    Query query=session.createQuery(“from Customer c right join c.orders o where c.name       like ‘zhao%’ ”);
    List list=query.list();
    for(int i=0;i<list.size();i++){
     Object[] objs=(Object[])list.get(i);
     Customer customer=(Customer) objs[0];
     order order=(Order)objs[1];
    }
          右外連接檢索,對集合元素的檢索策略以及返回結(jié)果集中的對象類型都采用與左外連接一樣的方式。
    4、交叉連接:
     對于不存在關(guān)聯(lián)關(guān)系的兩個實(shí)體對象,不能使用內(nèi)連接查詢,也不能使用外連接查詢,此時可以使用具有SQL風(fēng)格的交叉連接,如下面代碼:
    Select c.ID,c.name,c.age,o.ID,o.ordernumber,o.customer_ID
    From Customer c,Order o;
    這個HQL語句將會執(zhí)行交叉連接檢索,而且將會返回customer表和order表的笛卡兒積關(guān)聯(lián)結(jié)果。
    5、連接查詢運(yùn)行時檢索策略總結(jié):
    ①、如果在HQL和QBC查詢中沒有指定檢索策略,那么將會使用映射配置為件中指定的檢索策略,但是這里有一個例外,那就是HQL檢索總是會忽略實(shí)體映射配置文件中對關(guān)聯(lián)實(shí)體指定的迫切左外連接檢索策略,也就是說如果配置文件中指定對關(guān)聯(lián)實(shí)體采用迫切走外連接檢索,但是在HQL查詢語句中沒有指定這種檢索策略,此時Hibernate將會忽略這種檢索策略,而依然采用立即檢索。因此如果希望采用迫切左外連接檢索,就必須在HQL語句中明確指定。
    ②、如果在HQL或者QBC檢索中明確指定了檢索策略,就會覆蓋配置文件中的默認(rèn)檢索策略,在HQL查詢中通過left join fetch和inner join fetch來明確指定檢索策略,在QBC查詢中通過FetchMode.DEFAULT,FetchMode.EAGER,FetchMode.LAZY來明確指定檢索策略。
    ①、             目前的Hibernate的各種版本中,只允許在一個查詢中迫切左外連接檢索一個集合,即只允許存在一個一對多關(guān)聯(lián),但是允許存在多個一對一和多對多關(guān)聯(lián)。

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费h视频在线观看| 大地影院MV在线观看视频免费| 69xx免费观看视频| 伊人久久综在合线亚洲2019| 日韩视频免费在线观看| 亚洲成色www久久网站夜月| 国产真人无码作爱免费视频| 国产亚洲精品拍拍拍拍拍| 岛国精品一区免费视频在线观看| 国产亚洲AV夜间福利香蕉149| 国产免费A∨在线播放| 亚洲日本va在线视频观看| 日本在线看片免费| 亚洲专区中文字幕| 久久电影网午夜鲁丝片免费| 亚洲精华液一二三产区| 四虎免费久久影院| 久久99精品免费一区二区| 亚洲伊人久久大香线蕉苏妲己| 国产卡一卡二卡三免费入口 | 久久亚洲精品AB无码播放| 久9热免费精品视频在线观看| 亚洲福利视频一区二区三区| 24小时免费直播在线观看| 曰批全过程免费视频免费看| 亚洲日韩aⅴ在线视频| 免费精品国产日韩热久久| 综合偷自拍亚洲乱中文字幕| 国产亚洲日韩在线三区| 亚州免费一级毛片| 精品亚洲视频在线| 亚洲午夜久久久久妓女影院| 中文免费观看视频网站| 最新亚洲人成无码网www电影| 亚洲无人区午夜福利码高清完整版| 无码少妇精品一区二区免费动态| 亚洲欧美成人综合久久久| 久久影院亚洲一区| 成人男女网18免费视频| 大妹子影视剧在线观看全集免费 | 亚洲欧洲日产国码久在线|