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