hibernate中get()与load()的区别

 好久没用hibernate,好多东西都忘了,今天就来写写get()和load()的区别。

 下面用代码来说明:

 先建两个实体类,街道类(Jd)和区县类(Qx)是多对一关系。

 Jd:

 1 package com.Dto;
 2 
 3 public class Jd {
 4 
 5     private int jdid;
 6     private String jdname;
 7     private Qx qx=new Qx();
 8     public int getJdid() {
 9         return jdid;
10     }
11     public void setJdid(int jdid) {
12         this.jdid = jdid;
13     }
14     public Jd(int jdid, String jdname, Qx qx) {
15         super();
16         this.jdid = jdid;
17         this.jdname = jdname;
18         this.qx = qx;
19     }
20     public Jd() {
21         super();
22         // TODO Auto-generated constructor stub
23     }
24     @Override
25     public String toString() {
26         return "Jd [jdid=" + jdid + ", jdname=" + jdname + ", qx=" + qx
27                 + "]";
28     }
29     public String getjdname() {
30         return jdname;
31     }
32     public void setjdname(String jdname) {
33         this.jdname = jdname;
34     }
35     public Qx getQx() {
36         return qx;
37     }
38     public void setQx(Qx qx) {
39         this.qx = qx;
40     }
41     
42 }
View Code

   Jd的实体配置文件(Jd.hbm.xml):

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <class name="com.Dto.Jd" catalog="test" table="jd">
 7 
 8         <id name="jdid" type="java.lang.Integer">
 9             <column name="jdid" />
10             <generator class="native" />
11         </id>
12 
13         <property name="jdname" type="java.lang.String">
14             <column name="jdname" length="80" />
15         </property>
16 
17         <many-to-one name="qx" class="com.Dto.Qx">
18             <column name="qxid"></column>
19         </many-to-one>
20     </class>
21 
22 </hibernate-mapping>
View Code

Qx:

 1 package com.Dto;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class Qx {
 7 
 8     private int qxid;
 9     private String qxname;
10     private Set<Jd> jds =new HashSet<Jd>();
11     public int getQxid() {
12         return qxid;
13     }
14     public void setQxid(int qxid) {
15         this.qxid = qxid;
16     }
17     public String getQxname() {
18         return qxname;
19     }
20     public void setQxname(String qxname) {
21         this.qxname = qxname;
22     }
23     public Set<Jd> getJds() {
24         return jds;
25     }
26     public void setJds(Set<Jd> jds) {
27         this.jds = jds;
28     }
29     @Override
30     public String toString() {
31         return "Qx [qxid=" + qxid + ", qxname=" + qxname + ", jds=" + jds + "]";
32     }
33     public Qx(int qxid, String qxname, Set<Jd> jds) {
34         super();
35         this.qxid = qxid;
36         this.qxname = qxname;
37         this.jds = jds;
38     }
39     public Qx() {
40         super();
41         // TODO Auto-generated constructor stub
42     }
43     
44 }
View Code

Qx的实体配置文件(Qx.hbm.xml);

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <class name="com.Dto.Qx" catalog="test" table="qx">
 7         <id name="qxid" type="java.lang.Integer">
 8             <column name="qxid" />
 9             <generator class="native" />
10         </id>
11 
12         <property name="qxname" type="java.lang.String">
13             <column name="qxname" length="80" />
14         </property>
15 
16         <set name="jds" >
17             <key column="qxid"></key>
18             <one-to-many class="com.Dto.Jd" />
19         </set>
20     </class>
21 
22 </hibernate-mapping>
View Code

hibernate配置文件(hibernate.cfg.xml):

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory name="mySessionFactory">
 7         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 8         <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=UTF-8</property>
 9         <property name="hibernate.connection.username">root</property>
10         <property name="hibernate.connection.password">root</property>
11         <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
12         <property name="hibernate.show_sql">true</property>
13         <property name="hibernate.hbm2ddl.auto">update</property>
14         
15         <mapping resource="com/Dto/Jd.hbm.xml" />
16         <mapping resource="com/Dto/Qx.hbm.xml" />
17     </session-factory>
18 
19 </hibernate-configuration>
View Code

建一个获取sessionfactory的类HibernateSessionFactory:

 1 package com.until;
 2 
 3 import org.hibernate.SessionFactory;
 4 import org.hibernate.cfg.Configuration;
 5 
 6 public class HibernateSessionFactory {
 7 
 8     private static SessionFactory sessionFactory;
 9     static{
10         Configuration config=new Configuration().configure();
11         sessionFactory=config.buildSessionFactory();
12     }
13     public static SessionFactory getSessionFactory(){
14         return sessionFactory;
15     }
16 }
View Code

Dao这里就不写了,现在数据库里表中没有数据:

 Session session=HibernateSessionFactory.getSessionFactory().openSession();

1.当执行如下语句时:并没有生成sql语句。
Jd jd1=(Jd) session.load(Jd.class, 0);

2.当执行上述相同语句,但在Jd.hbm.xml配置文件中,“<class name="com.Dto.Jd" catalog="test" table="jd" lazy="false">”中加上lazy="false"时:

生成了sql语句,但同时报错:“ org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.Dto.Jd#0]”

3.当执行如下语句时:

Jd jd1=(Jd) session.load(Jd.class, 0);
jd1.getjdname();

生成了sql语句,同时报错:“org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.Dto.Jd#0]”

4.当街道表中有该id对应的数据时,就不会报上述错误。

5.当执行如下语句时:

Jd jd2=(Jd) session.get(Jd.class, 0);

生成了sql语句:“Hibernate: select jd0_.jdid as jdid0_0_, jd0_.jdname as jdname0_0_, jd0_.qxid as qxid0_0_ from test.jd jd0_ where jd0_.jdid=?”

通过上诉代码总结:

1.get和load是根据id取得一个记录

2.load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常,get方法检索不到的话会返回null。

3.get方法直接从数据库中检索,而load方法的执行则比较复杂首先查找session的persistent Context中是否有缓存,如果有则直接返回 如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常 如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null 在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target上,并将initialized=true,如果 找不到就抛出异常。

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

posted @ 2013-05-22 15:21  宅山仔  阅读(328)  评论(0编辑  收藏  举报