Hibernate的get和load方法的区别

Hibernate的get和load方法都是用于查询一条记录,但是他们又很大的区别。

1.从加载方法上对比:

get方法不支持延迟加载,而load支持延迟加载。

2.从返回结果上对比:
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常
get方法检索不到的话会返回null。

3.从检索执行机制上对比:

get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。

来看具体的例子:

首先是一个持久化类:

public class Pet {
	
	private String userName;
	private String password;
	private int id;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	
}

 

 

下面是Hibernate的核心配置文件hibernate-cfg.xml代码:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
	<property name="connection.username">sa</property>
	<property name="connection.url">
		jdbc:jtds:sqlserver://localhost:1433/epet
	</property>
	<property name="dialect">
		org.hibernate.dialect.SQLServerDialect
	</property>
	<property name="myeclipse.connection.profile">pet</property>
	<property name="connection.driver_class">
		net.sourceforge.jtds.jdbc.Driver
	</property>
	
	<property name="show_sql">true</property>
    <property name="format_sql">true</property>
	
	<mapping resource="com/info/po/Pet.hbm.xml" />
	
</session-factory>

</hibernate-configuration>

 

下面是hibernate的另一个配置文件Pet.hbm.xml的代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
	<class name="com.info.po.Pet" table="login">
		<id name="id" column="id" type="int">
			<generator class="increment"></generator>
		</id>
		<property name="userName" column="username" type="string"></property>
		<property name="password" column="password" type="string"></property>
	</class>
		
</hibernate-mapping>

 

再就是重要的DAO代码了:

import org.hibernate.Session;
import org.hibernate.Transaction;
public class PetDAO {
	
	public void getPetById(int id){
		Session session = HibernateSessionFactory.getSession();
		Pet pet = (Pet)session.load(Pet.class, id);
		System.out.println(pet.getid());
		session.close();
		
	}
	
}

 

最后是测试类代码:

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		PetDAO dao = new PetDAO();
		dao.getPetById(10);
	}
	
}

数据库里面的表的结构为:

 

idusernamepassword
2aaa111
3bbb222
4ccc333
5ddd444

上面是使用的是get方法,运行以上代码,结果是:

Exception in thread "main" java.lang.NullPointerException

 而改用load方法的话,运行发的结果是:

Exception in thread "main" org.hibernate.ObjectNotFoundException

 而如果将将上面的dao代码稍微改下,把System.out.println(pet.getId())放到session.close()之后,

public void getPetById(int id){
		Session session = HibernateSessionFactory.getSession();
		Pet pet = (Pet)session.load(Pet.class, id);
		
		session.close();
		System.out.println(pet.getUserName());
	}

 
同样是使用load方法,但是运行的结果却不一样:

Exception in thread "main" org.hibernate.LazyInitializationException

 结论:

 对于Hibernate get方法,Hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查询数据库,数据库中没有就返回null。

需要注意的是:下面这两段代码不会去执行数据库,因为load后会在hibernate的一级缓存中存放一个map对象,该map的key就是id的值,但是当你getId的时候,它会去一级缓存里拿map的key值,而不会去执行数据库查询,也不会保错。

Pet pet = (Pet)session.load(Pet.class, id);
System.out.println(pet.getUserName());

 

 文章最后,附上本文的源代码,如有不对的地方,晴大家多多指正。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值