美文网首页SSHM四大框架
Hibernate之抓取策略

Hibernate之抓取策略

作者: 昵称已被占用了啊 | 来源:发表于2016-08-20 15:25 被阅读27次

    如果有一对多或者多对一的关联情况时:就要考虑抓取策略了。

    如果不开启抓取策略,会分别发出sql语句来查询。如果有抓取策略,会在一次查询的时候把所有关联对象也会查询出来。

    Student stu = (Student)session.load(Student.class, 1);

    System.out.println(stu.getName()+","+stu.getClassroom().getName()+","+

    stu.getClassroom().getSpecial().getName());

    对于xml配置而言,默认情况就会发出三条sql语句,每一条sql取相应的对象,一条取Student,一条取Classroom,一条取Special。

    可以通过设置添加:<many-to-onename="classroom"column="cid"fetch="join">

    来设置join的抓取策略

    Student

    此时还会发出两条sql语句,还需要设置Classroom中的<many-to-onename="special"column="spe_id"fetch="join">来设置join的抓取策略

    此时就会发出一条sql语句了,会通过join自动抓取所有关联的数据。

    但是抓取策略并不一定都是好的,使用fetch="join"虽然可以将关联对象一并抓取,但是即使不使用关联对象也会一并抓取出来,这样会占用相应的内存。延迟加载就失效了。

    以下查询:

    List<Student>stus = session.createQuery("from Student").list();

    for(Student stu:stus) {

    System.out.println(stu.getName()+","+stu.getClassroom());}

    还是会发出很多sql语句。

    原因是:

    在XML中配置了fetch=join仅仅只是对load的对象有用,对HQL中查询的对象无用,真正涉及到creatQuery查询的时候,即使添加fetch="join"也无效。

    所以此时会发出查询班级的SQL,解决的这个SQL的问题有两种方案,

    1.一种是设置被关联对象的抓取的batch-size

    Classroom

    2.另一种方案在HQL中使用fecth来指定抓取

    List<Student>stus = session.createQuery("select stu from Student stu join fetch stu.classroom ").list();

    for(Student stu:stus) {

    System.out.println(stu.getName()+","+stu.getClassroom());}

    此时会发出一条sql语句

    特别注意,如果使用了join fetch就无法使用count(*)




    对于Annotation的配置而言,默认就是基于join的抓取的,所以load的那个只会发出一条SQL。

    但是当creatquery查询多条数据有关联对象的时候:

    由于基于Annotation的配置没有延迟加载,此时会把所有的关联对象查询上来,发大量的SQL语句,所以要设置延迟加载:

    由于启用了student的延迟加载,但是并没有启用classroom的延迟加载,所以上面的load语句会发出两条sql。

    @ManyToOne(fetch = FetchType.EAGER)相当于xml中的

    <many-to-onename="classroom"column="cid"fetch="join">

    @ManyToOne(fetch = FetchType.LAZY)相当于xml中的

    <many-to-onename="classroom"column="cid"fetch="select">

    如果是后者的话,可以设置

    1.

    2 join feach

    和xml基本类似。

    以上是多的一方的查询

    一的一方load的时候,可以设置set的feach="join"

    一方creatQuery的时候

    对于通过HQL取班级列表并且获取相应的学生列表时,fecth=join就无效了

    * 第一种方案可以设置set的batch-size来完成批量的抓取

    * 第二中方案可以设置fetch=subselect,使用subselect会完成根据查询出来的班级进行一次对学生对象的子查询

    相关文章

      网友评论

      • liuxue:哎哟,不错哦,继续加油!!!!

      本文标题:Hibernate之抓取策略

      本文链接:https://www.haomeiwen.com/subject/rjlisttx.html