Hibernate之get和load的区别

Hibernate从数据库获取对象有两种方式,为get和load。

当load方式获取对象,会使用hibernate的延迟加载机制。

load01

public void load01(){
	Session session = HibernateUtil.getCurrentSession();
	session.beginTransaction();
	User user = session.load(User.class, 1);
	//System.out.println("userName = "+user.getUserName());
	session.getTransaction().commit();
}

session.load获取user对象,并不会发出select sql语句;如果注释中的user.getUserName()执行,才会有select sql语句,且select语句在userName值打印之前。也就是说使用user对象会先触发去查询user对象。

load02

public void load02(){
	Session session = HibernateUtil.getCurrentSession();
	session.beginTransaction();
	User user = session.load(User.class, 1);
	System.out.println("userName = "+user.getId());
	session.getTransaction().commit();
}

此处使用了user对象去获取id,但并不会有select sql语句

load03

public void load03(){
	Session session = HibernateUtil.getCurrentSession();
	session.beginTransaction();
	User user = session.load(User.class, 1);
	System.out.println("userObject = "+user);
	session.getTransaction().commit();
}

会发送select sql语句,再打印对象值。

结论:当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来一个代理对象。该代理对象只保存了实体类对象的id(主键字段)。当要使用这个对象,得到其它属性时,才会发送select sql语句去查询需要的对象。

get01

public void get01(){
	Session session = HibernateUtil.getCurrentSession();
	session.beginTransaction();
	User user = session.get(User.class, 1);
	System.out.println("------------- User GET -------------");
	session.getTransaction().commit();
}

select sql语句在User GET之前就已经发送。

结论:get方法是立即从数据库获取对象。

get02

public void get02(){
	Session session = HibernateUtil.getCurrentSession();
	session.beginTransaction();
	User user = session.get(User.class, 2);
	System.out.println("------------- User GET -------------");
	user.getUserName();
	session.getTransaction().commit();
}

id=2的user对象不存在,不使用user对象的其它属性 Done entity load : com.ack.hibernate.User#2;

此示例加了user.getUserName(),则会报:java.lang.NullPointerException

load04

public void load04(){
	Session session = HibernateUtil.getCurrentSession();
	session.beginTransaction();
	User user = session.load(User.class, 2);
	user.getUserName();
	session.getTransaction().commit();
}

不获取user的属性时未真正到数据库中去查,不报错。此示例中加了user.getUserName(),报错:org.hibernate.ObjectNotFoundException

public class UserDao {
	public User loadUser(int id){
		Session session = null;
        Transaction tx = null;
        User user =  null;
        try{
            session = HibernateUtil.getCurrentSession();
            tx = session.beginTransaction();
            user = (User)session.load(User.class, 1);
            tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }finally{
        }
        return user;
    }
}
public void load05(){
	UserDao userDao = new UserDao();
	User user = userDao.loadUser(2);
	user.getUserName();
}

模拟了一个UserDAO这样的对象,然后我们在测试用例里面来通过load加载一个对象,此时我们发现控制台会报LazyInitializationException异常。异常原因:因为load的延迟加载机制,当我们通过load()方法来加载一个对象时,此时并没有发出sql语句去从数据库中查询出该对象,当前这个对象仅仅是一个只有id的代理对象,我们还并没有使用该对象,但是此时我们的session已经关闭了,所以当我们在测试用例中使用该对象时就会报LazyInitializationException这个异常了。

所以以后我们只要看到控制台报LazyInitializationException这种异常,就知道是使用了load的方式延迟加载一个对象了,解决这个的方法有两种,一种是将load改成get的方式来得到该对象,另一种是在表示层来开启我们的session和关闭session。
参考自:http://www.cnblogs.com/xiaoluo501395377/p/3371776.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值