• hibernate抓取问题


    当使用xml配置类之间的关系时 ,例如 学生 班级,多对一关系

        /**

                 * 默认情况会发出2条SQL语句,一条取student,一条取Classroom,其实这只需要一条sql
                 * 解决办法  通过设置XML中的<many-to-one name="classroom" column="cid" fetch="join"/> //默认fetch=select
                 * 可以完成对抓取的设置
                 */
                session = HibernateUtil.openSession();
                Student stu = (Student)session.load(Student.class, 1); //只查一个学生
                System.out.println(stu.getName()+","+stu.getClassroom().getName()) 

    -----------------------------------------------------------------------------------------------------

          缺点。有时候不需要班级信息也会查出来,占用内存 ,延迟加载就不起作用了

         session = HibernateUtil.openSession();
                Student stu = (Student)session.load(Student.class, 1);
                //延迟加载就失效,自动查班级信息
                System.out.println(stu.getName());

    -----------------------------------------------------------------------------------------------------------------

        但是当查询所有学生时 使用xml配置。并且使用fetch=join 如下代码 又会发查询学生sql和班级的sql

        List<Student> stus = session.createQuery("from Student").list(); //查询全部学生
                for(Student stu:stus) {
                    System.out.println(stu.getName()+","+stu.getClassroom().getName());
                }

         在XML中配置了fetch=join仅仅只是对load的对象有用,对HQL中查询的对象无用

         解决办法1 。设置查询班级的数量  batch-size,但是查询的数据随着session关闭就没了,

        <class name="Classroom" table="t_classroom" batch-size=''20''>

        解决办法 2 使用fetch关键字 在hql中  ,如果使用了join fetch就无法使用count(*)

        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());
                }

    -------------------------------------------------------------------------------------------------------------------

    当使用annotation配置类之间关系时。

    ----------------------------------------------------------------------------------------------------------

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

         session = HibernateUtil.openSession();
         Student stu = (Student)session.load(Student.class, 1); //只查一个学生
                System.out.println(stu.getName()+","+stu.getClassroom().getName());

    -------------------------------------------------------------------------------------------------------

        但是annotation默认没有延迟加载。如果查询全部学生。会自动查处关联的班级信息。发大量sql语句 这也是个问题

        List<Student> stus = session.createQuery("from Student").list(); //查所有学生
                for(Student stu:stus) {
                    System.out.println(stu.getName());
                }

        解决 使用annotation时设置ManToOne(fetch=FetchType.Lazy)  延迟加载 相当于xml配置中 默认也就是fetch='select'

        影响 1 但是一下代码又会发2条sql

          session = HibernateUtil.openSession();
                Student stu = (Student)session.load(Student.class, 1);
                System.out.println(stu.getName()+","+stu.getClassroom().getName())

        影响 2     

        当又想查询所有学生和所在班级信息 如下代码,又会发多条SQL。查学生SQL。和班级SQL

        List<Student> stus = session.createQuery("from Student").list();
                for(Student stu:stus) {
                    System.out.println(stu.getName()+","+stu.getClassroom().getName());
                }

    ------------------------------------------------------------------------------------------------------

        @ManyToOne(fetch=FetchType.LAZY)//LAZY就是XML中的select,EAGER就表示XML中的join

        annotation默认是EAGER

                 @BatchSize(size=20)
                 public class Classroom   相当于xml中的batch-size 设置

    -------------------------------------------------

    总结,当你使用xml时。默认有延迟。当查询一个对象时。同时也查他的关联对象,会发多条sql。先查对象,再发sql查关联对象。使用fetch=join配置,也是只对load对象有用(就是load方法里传的class),hql中的对象(hibernate自己发送的hql语句中查询的对象)没用还是发好几条sql.解决要不就设置batch-size要不就自己用 join fetch 自己写hql

    使用annotation时,默认是没延迟。查询一个对象。只发一条。但是查询多个对象时 ,又和xml中使用fetch=join 的情况一下样 ,但是你设置fetcg=FetchType.LAZY ,查询单一对象时,又会发两条,所以 要不就设置batch-size要不就自己用 join fetch 自己写hql

    所以有时候。用别人的东西。不了解别人的东西就会问题很多。但你花很多时间去研究他。不如花时间研究数据库,用原生 sql ,

    懂数据库的人,可能不用hibernate, 想用好还得精通hibernate。

    不懂数据库的人。估计也不会花心思研究hibernate。研究了hibernate。你还得懂数据库

  • 相关阅读:
    jQuery及javascript DOM创建节点(三)
    jQueryEasyUI Window的基本使用
    3.1、值类型
    手动依赖注入(二)
    3.1.2、字符类型
    不错不错
    我们应该讨论什么? 就面向对象的讨论所引发的一些思考
    保存个地址, 顺便问个问题~
    嗯嗯, 今天很高兴
    方法级AOP: 又一个补丁
  • 原文地址:https://www.cnblogs.com/or2-/p/3512093.html
Copyright © 2020-2023  润新知