`
alfredgao
  • 浏览: 134238 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

hibernate的load和get方法的区别

阅读更多
hibernate的load和get方法的区别
2008-07-09 11:14

1)当数据库不存在对应ID数据时,调用load()方法将会抛出ObjectNotFoundException异常,get()方法将返回null.下面是一个简单的测试数据库中没有id为2的person

2)也就是延时加载的区别。load的方法默认要加载的对象是存在数据库中的,返回的是一个代理对象而不是一个真正的类实例,当用到具体与数据库有关的数据时候才查询数据库,而get方法直接查询数据库,返回类的实例。例如上面的例子,运行到(1)直接输出sql语句,而(3)却没有输出,在(5)输出了一条sql语句,由于所查询的对象不存在抛出ObjectNotFoundException异常。关于类的代理对象可以通过debug调试的到。但是如果在内部内存中存在所要查询的对象,无论对象是代理的(load出来的)还是类的实例(get出来的)都会返回内存中的形态。

3)第三点区别就是:“,get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。”这是从别的地方听说的。

 

================================================

2008-05-22 11:45

面试的题目是load和get方法的区别,平时也就知道用这两个方法,还真不知道有什么区别!回来后查了查,自己做了一下验证终于理解了二者的不同!一下哦我们以一个例子来讲解一下。

 

package hib;

/**
* @hibernate.class table="PERSON"
* @author Administrator
*
*/
public class Person {

private int id;

private String name = "jiaji";

/**
* @hibernate.id generator-class="native"
* @return the id
*/
public int getId() {
   return id;
}

/**
* @param id
*            the id to set
*/
public void setId(int id) {
   this.id = id;
}

/**
* @hibernate.property length="20"
* @return the name
*/
public String getName() {
   return name;
}

/**
* @param name
*            the name to set
*/
public void setName(String name) {
   this.name = name;
}

}

映射文件Personhbm.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="hib.Person" table="PERSON" lazy="true">

   <id name="id" column="id" type="int">
    <generator class="native">
    </generator>
   </id>

   <property name="name" type="java.lang.String" update="true"
    insert="true" column="name" length="20" />

</class>

</hibernate-mapping>

hibernate配置文件,为了查看试验结果设置 <property name="show_sql">true</property>由于显示sql语句

<?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">root</property>
<property name="connection.url">
   jdbc:mysql://localhost:3306/data
</property>
<property name="dialect">
   org.hibernate.dialect.MySQLDialect
</property>
<property name="myeclipse.connection.profile">mysql</property>
<property name="connection.password">jiajw</property>
<property name="connection.driver_class">
   com.mysql.jdbc.Driver
</property>

<property name="jdbc.fetch_size">50</property>
<property name="show_sql">true</property>
<property name="createtable">false</property>
<property name="updatetable">true</property>
<property name="c3p0.min_size">2</property>
<property name="c3p0.max_size">5</property>
<property name="c3p0.max_statements">100</property>
<property name="c3p0.idle_test_period">5000</property>
<mapping resource="hib/Person.hbm.xml" />

</session-factory>

</hibernate-configuration>

言归正传,一下介绍两种方法的三点区别:

1)当数据库不存在对应ID数据时,调用load()方法将会抛出ObjectNotFoundException异常,get()方法将返回null.下面是一个简单的测试数据库中没有id为2的person。

package hib;

import org.hibernate.Session;
import org.hibernate.Transaction;

public class Test {

public static void main(String[] args) {
   Session session = HibernateSessionFactory.getSession();
   Transaction transaction = session.beginTransaction();
   Person p = (Person) session.get(Person.class, 2);(1)
   System.out.println("p="+p);(2)
   Person p1 = (Person) session.load(Person.class,2);(3)
   System.out.println("arrived here");(4)
   System.out.println(p1.getName());(5)
   session.close();
}
}

 

运行结果如下

 

 

 

 

 

 

 

2)也就是延时加载的区别。load的方法默认要加载的对象是存在数据库中的,返回的是一个代理对象而不是一个真正的类实例,当用到具体与数据库有关的数据时候才查询数据库,而get方法直接查询数据库,返回类的实例。例如上面的例子,运行到(1)直接输出sql语句,而(3)却没有输出,在(5)输出了一条sql语句,由于所查询的对象不存在抛出ObjectNotFoundException异常。关于类的代理对象可以通过debug调试的到。但是如果在内部内存中存在所要查询的对象,无论对象是代理的(load出来的)还是类的实例(get出来的)都会返回内存中的形态。

Session session = HibernateSessionFactory.getSession();
   Transaction transaction = session.beginTransaction();
   Person p = (Person) session.get(Person.class, 1);
     System.out.println("arrived here");
   System.out.println(p.getName());
   session.close();

调试结果为:

如果把get方法改成 load方法结果就不一样

 

 

3)第三点区别就是:“,get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。”这是从别的地方听说的。

 

 

hibernate get load 区别

1、hibernate中get方法和load方法的根本区别在于:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。
对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。

2、虽然好多书中都这么说:“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。

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

总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

分享到:
评论

相关推荐

    hibernate中get和load方法的区别

    NULL 博文链接:https://ysj5125094.iteye.com/blog/1897557

    hibernate get load区别

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

    Hibernate的get和load方法的区别

    NULL 博文链接:https://811417208-qq-com.iteye.com/blog/506950

    hibernate 三种 查询 方式 load与get的区别

    NULL 博文链接:https://cici9898-007.iteye.com/blog/1847710

    Hibernate中get和load方法的区别以及close(),clear()、evict()等的区别

    get和load方式是根据id取得一个记录 下边详细说一下get和load的不同,因为有些时候为了对比也会把find加进来。 1.从返回结果上对比: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法...

    Hibernate查询 load与get的区别及其它查询测试

    NULL 博文链接:https://quicker.iteye.com/blog/658451

    hibernate中get和load的区别共5页.pdf

    hibernate中get和load的区别共5页.pdf.zip

    Hibernate中load方法与get方法的区别

    Hibernate中有两个极为相似的方法get()与load(),他们都可以通过指定的实体类与ID从数据库中读取数据,并返回对应的实例,但Hibernate不会搞两个完全一样的方法的

    Hibernate中get()和load()的区别.docx

    Hibernate中根据Id单条查询获取对象的方式有两种,分别是get()和load(),来看一下这两种方式的区别。 1. get() 使用get()来根据ID进行单条查询: User user=session.get(User.class, "1"); 当get()方法被调用的时候...

    Hibernate中Session.get()方法和load()方法的详细比较

    今天小编就为大家分享一篇关于Hibernate中Session.get()方法和load()方法的详细比较,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    hibernate get/load/saveOrUpdate/statistics

    博文链接:https://log-cd.iteye.com/blog/205166

    Hibernate学习笔记

    Hibernate 学习笔记 get和load的区别 一对一,一对多,多对多 悲观锁,乐观锁 hibernate查询语言hql hibernate一级缓存、二级缓存 抓取策略

    hibernate操作数据库笔记

    //该方法将到classpath下解析hibernate.cfg.xml中的配置,如果不用Hibernate默认的配置文件名和路径,可在该方法中指定Hibernate配置文件的名称和路径 2.用Configuration对象获取SessionFactory和Session对象:...

    hibernate查询与缓存

    Hibernate查询首先介绍get()和load()方法的区别:get()方法和load()方法的区别主要在于对二级缓存的使用上。load()方法会使用二级缓存,而get()方法在一级缓存没有找到会直接查询数据库,不会去二级缓存中查找。 get...

    hibernate基础教程

    2、load()方法 3、批量存储:session.flush()和session.clear() 二 Hibernate中的二级缓存结构 在Hibernate中使用两极缓存结构,第一级缓存是Session级别的缓存,...

    传智播客李勇hibernate源码1-20课

    04_Session接口及get|load|persist方法 05_实体对象的三种状态与saveOrUpdate方法 06_完善HibernateUtil类及hql查询入门 07_实体类或属性名与数据库关键字冲突问题 10_使用Hibernate完成CRUD实验的步骤说明 11_...

    Hibernate入门文档

    Hibernate 难点解析: hibernate中uuid和...Hibernate get与load的区别 hibernate二级缓存中list和iterator的用法 Hibernate中的对象有三种状态: lock和update区别 save 和update区别 update 和saveOrUpdate区别

Global site tag (gtag.js) - Google Analytics