代码改变世界

5、Hibernate的延迟加载

2015-10-03 22:53  怡红院丿无痕  阅读(216)  评论(0编辑  收藏  举报

1、session.load(User.class,1);

一:了解懒加载

        Session session = null;
        try {
            session = HibernateUtil.openSession();
            User u = (User)session.load(User.class, 1);
            //此时一条sql都没有发,这就是hibernate的延迟加载
            /**
             * 延迟加载指的就是,当完成load操作之后,并不会马山发出sql语句,只有在使用到该对象时才会发出sql
             * 当完成load之后,u其实是一个代理对象,这个代理对象中仅仅只有一个id的值
             */
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HibernateUtil.close(session);
        }

二:清楚什么情况下,会发sql语句

  当完成load之后,u其实是一个代理对象,这个代理对象中仅仅只有一个id的值。
所以System.out.println( u.getId() )。也不会发出sql语句。
但是由于name没有值,所以System.out.println( u.getName() ),会发出sql语句。因为必须去数据库取数据。
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            User u = (User)session.load(User.class, 1);
            //此时一条sql都没有发,这就是hibernate的延迟加载
            /**
             * 延迟加载指的就是,当完成load操作之后,并不会马山发出sql语句,只有在使用到该对象时才会发出sql
             * 当完成load之后,u其实是一个代理对象,这个代理对象中仅仅只有一个id的值
             */
            //此时不会发sql,因为代理对象中知道id的值
             System.out.println(u.getId());
            //name没有值,必须去数据库中取。所以会发出sql
            System.out.println(u.getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HibernateUtil.close(session);
        }

2、session.get(User.class,1);

一:get()没有延迟加载,只要一调用,就会发出sql语句。
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            //get是只要一执行就会发出sql,get没有延迟加载
            User u = (User)session.get(User.class, 1);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HibernateUtil.close(session);
        }

3、在使用session.get()或者session.load()可能会出现的问题

    一:使用session.get()去加载,一个数据库不存在的记录,会出现NullPointerException

         因为,数据库中没有session.get()要加载的记录.所以get()方法会返回一个Null,

         所以调用System.out.println( u.getId() ) 就会出现NullPointerException异常。

        

        Session session = null;
        try {
            session = HibernateUtil.openSession();
            //get是只要一执行就会发出sql,get没有延迟加载
            User u = (User)session.get(User.class, 101);
            //此时由于取了这个数据,发现数据库中并没有该数据,所以u是null,所以会抛出空指针异常
            System.out.println(u.getId());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HibernateUtil.close(session);
        }

      二:使用session.load()去加载,一个数据库不存在的记录,会出现ObjectNotFoundException

           (1)对于u.getId(),由于代理对象,包含id的数值。故不会抛出异常。所以System.out.println( u.getId() ),会输出一个数值。

           (2)对于u.getName(),由于代理对象中不包含name的值,所以System.out.println( u.getName() ),回去数据库中寻找这条记录.

               又因为数据库没有这条记录,但是由于代理对象又有id的数值,故代理对象不为null,此时,回报一个,org.hibernate.ObjectNotFoundException的异常.

        Session session = null;
        try {
            session = HibernateUtil.openSession();
            User u = (User)session.load(User.class, 101);
            //由于id已经存在,所以不会抛出异常
            System.out.println(u.getId());
            //此时会去数据库中取数据,发现没有这个对象,但是u并不是空,所以会抛出ObjectNotFoundException
            System.out.println(u.getNickname());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HibernateUtil.close(session);
        }

     三:在Session关闭后,去调用代理对象的除了id的其它属性

         使用了load,load是有延迟加载的,返回的时候的u是一个代理对象,仅仅只有一个id,

        但是在返回的时候Session已经被关闭了,此时当需要使用u的其他属性时就需要去数据库中,

       但是Session关闭了,所以就抛出org.hibernate.LazyInitializationException no session

       

        /*
         * 由于使用了load,load是有延迟加载的,返回的时候的u是一个代理对象,仅仅只有一个id
         * 但是在返回的时候Session已经被关闭了,此时当需要使用u的其他属性时就需要去数据库中
         * 但是Session关闭了,所以就抛出org.hibernate.LazyInitializationException no session
         */
        UserDao ud = new UserDao();
        User u = ud.load(2);
        System.out.println(u.getUsername());