zoukankan      html  css  js  c++  java
  • Hibernate中1+N问题以及解决方法

    1. Hibernate中的1+N问题描述   

            在多对一关系中,当我们需要查询多的一方对应的表的记录时,可以用一条sql语句就能完成操作。然而,在多的一方的实体类中的@ManyToOne标注的fetch的默认值是fetchType.EAGER,这时,hibernate除了发出查询多的一方对应的表的记录的sql语句外,还会发出n(多方记录数)条sql语句,这就是1+n问题。如:bbs的板块(Category),主题(topic),回复(msg)。一个板块有多个主题,而一个主题属于一个板块,则Category和topic属于一对多的关系,在topic里设置@ManyToOne。当需要取出所有的主题时,只需要发出select * from topic一条语句就能做到。然而,hibernate会查询出每个topic所对应的Category,所以会发出1+n条sql语句。

    2. 1+N问题的解决办法

        ①设置@ManyToOne的fetch属性值为fetchType.LAZY,这种方式解决后,后面的n条sql语句按需而发。但是有个弊端,就是如果需要级联查询就无法获取级联对象了。

        ②设置@BatchSize(size=5)(该注解要加在类上面,跟@Entity在同一位置),这样发出的sql语句减少。这个设置在一定程度上提高了效率。

        ③在hqp语句中使用用join fetch,事实上Criteria用的就是这种方法。这也是最常用的方法;

    1.  
      @Test
    2.  
      //join fetch
    3.  
      publicvoid test1_N3(){
    4.  
      Session session=sf.getCurrentSession();
    5.  
      session.beginTransaction();
    6.  
      //List<Topic> topics=(List<Topic>)session.createCriteria(Topic.class).list();//只有一条查询语句,Criteria方法就是这种方式
    7.  
      List<Topic> topics=(List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list();
    8.  
      for (Topic t:topics) {
    9.  
      System.out.println(t.getId()+"----"+t.getTitle());
    10.  
      System.out.println(t.getCategory().getName());
    11.  
      }
    12.  
      session.getTransaction().commit();
    13.  
      }

            这就是Hibernate中的1+N问题

  • 相关阅读:
    luogu P1330 封锁阳光大学 x
    luoguP3353 在你窗外闪耀的星星
    luogu小金明qwq x
    [HDOJ5093] Battle ships(最大匹配)
    [HDOJ5092] Seam Carving(DP,记录路径)
    [UVA1449] Dominating Patterns(AC自动机,STL,计数,神坑)
    [POJ3057]Evacuation(二分图匹配,BFS,二分,好题)
    [POJ3041]Asteroids(二分图,最大匹配)
    [POJ2195]Going Home(带权最大匹配,KM,最小费用流)
    [codeVS1917] 深海机器人问题(费用流,拆边)
  • 原文地址:https://www.cnblogs.com/hadley/p/9557683.html
Copyright © 2011-2022 走看看