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

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

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

    隨筆-95  評論-31  文章-10  trackbacks-0
    JPA
    要想徹底解決1+N的問題,即查詢one的時候級聯(lián)出many,多出N個select語句。

    1:加Fetch=FetchType.Lazy沒用,這個只能緩解,但是使用的時候即one.many.iterator()的時候還是會發(fā)送N條select語句
    2:加@Fetch(JOIN)也沒用,這個屬于Hibernate提供的注解, 調(diào)用entityManager.find()或者自定義createQuery(jpql),雖然會使用外連接,但是一旦調(diào)用one.many.iterator的時候 還是避免不了發(fā)送select語句,除非jpql里面避免實體的查詢,只查詢實體屬性值,即返回值是個Object[],這樣可避免,因為沒有機會調(diào)用one.many.iterator方法,都是實體屬性值。

    最終解決方法是: jpql調(diào)用left/right/inner join fetch語句,主要是加fetch,不加效果仍然一樣,這樣即可避免調(diào)用one.many.iterator時發(fā)送N條select語句,只有一條外連接語句,它會無視FetchType屬性Lazy還是eager。

    示例: A---->B  @oneToMany   A1 B多

     1 //示意代碼
     2 public class A{
     3 @OneToMany(cascade={CascadeType.All},fetch=FetchType.Lazy,mappedBy="a")
        //mappedBy表示當(dāng)前實體不維護(hù)外鍵,外鍵在多的一方維護(hù),即保存B的時候會保存A,也可設(shè)置為允許為null

     4 private Set<B> bSet;
     5 
     6 }
     7 @Test
     8 public void test(){
     9       //最常見方式 
    10       //第一種
    11       A a = entityManager.find(A.class,1L);
    12       a.bSet.iterator();//觸發(fā)N條select語句
    13 
    14       //第二種
    15       Query query = entityManager.createQuery(select a from A a );     
    16       List<A> aList = query.getResultList();
    17       aList.get(0).bSet.iterator();//觸發(fā)N條select語句
    18 
    19       //第三種
    20       Query query = entityManager.createQuery(select a from A a left join a.bSet b where a.id=?1);
    21       List<A> aList = query.getResultList();
    22       aList.get(0).bSet.iterator();//觸發(fā)N條select語句
    23       
    24       //第四種
    25       Query query = entityManager.createQuery(select a.name,b.name from A a left join a.bSet b where a.id=?1);
    26       List
    <Object[]> aList=query.getResultList(); //返回值是數(shù)組,即是a.name和b.name沒有地方觸發(fā)N條select語句
    27    
    28       //第五種
    29       Query query = entityManager.createQuery(select a,b.name,b.id from A a left join a.bSet b where a.id=?1);
    30       List
    <Object[]> aList=query.getResultList(); //返回值是數(shù)組,即a實體和b.name,b.id
    31       (A)(aList.get(0)[0]).bSet.iterator()//觸發(fā)N條select語句。
    32 
    33       //第六種
    34       Query query = entityManager.createQuery(select a from A a left join fetch a.bSet b where a.id=?1);
    35       List<A> aList = query.getResultList();
    36       aList.get(0).bSet.iterator();//不會觸發(fā)N條select語句
    37       //這里比第五種只多加了個fetch,就不會出現(xiàn)N條select語句
    38                
    39 }


    理論上JPA實體只要映射好關(guān)系,A--->B--->C--->D....... 只需from A 即可查詢出B C D, 但這樣做會影響性能,因為實際中我們可能只需要不同表的若干屬性,而不是全部,所以首先有了LAZY,但是它只能緩解,真正使用的時候還是會觸發(fā)N條select語句,所以我們又希望一條join語句搞定,一般情況下,只需要使用left/right/inner join 即可,不需要加fetch,前提是select后面跟的是實體屬性而不是實體,而一旦跟上實體,那么由該實體獲取多的一方數(shù)據(jù)時,仍然會觸發(fā)N條select語句,這個時候就要強制加上xxxx join fetch即可避免。

    所以想避免one.many.iterator獲取多的一方數(shù)據(jù)觸發(fā)N條select語句,那么只有兩種辦法
    1: select 后面跟實體屬性,不要跟實體, 再使用join。
    2: 如果select 后面一定要跟實體,那么使用xxxx join fetch,這樣即使one.many.iterator的時候也不會觸發(fā)N條select語句。


    posted on 2015-07-20 17:04 朔望魔刃 閱讀(341) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 成人毛片18女人毛片免费| 伊人久久大香线蕉亚洲五月天 | 免费毛片在线播放| 深夜免费在线视频| 久久亚洲国产成人精品性色| 最近免费中文字幕视频高清在线看 | 亚洲精品A在线观看| 无码人妻一区二区三区免费看| 亚洲最大的黄色网| 亚洲综合在线另类色区奇米| 久久久久久免费视频| 一级女人18片毛片免费视频| 亚洲理论片在线中文字幕| 免费在线观看一级毛片| 亚洲一区免费观看| 特黄特色大片免费| 亚洲精品国产免费| 中文字幕亚洲专区| 妞干网在线免费视频| 日本免费中文视频| 亚洲AV女人18毛片水真多| 亚洲自偷自偷精品| 亚洲毛片不卡av在线播放一区| 免免费国产AAAAA片| 热99RE久久精品这里都是精品免费| 亚洲色成人WWW永久在线观看| 国产亚洲精品无码成人| 在线观看国产情趣免费视频 | 久久亚洲国产成人影院网站| 18禁免费无码无遮挡不卡网站| 国产日韩在线视频免费播放| 亚洲综合在线一区二区三区| 亚洲av无码乱码国产精品| 亚洲国产成人久久笫一页| 欧美a级在线现免费观看| 久久99免费视频| 一级一级一片免费高清| 亚洲国产AV一区二区三区四区| 亚洲美女精品视频| 久久久久亚洲AV成人无码网站 | 国产亚洲欧洲Aⅴ综合一区|