1.立即检索:当执行到session.load(Class,Index)语句时,立即执行了Sql语句操作。
2.延迟检索:当执行到session.load(Class,Index)语句时,没有立即执行了Sql语句操作,只有当访问到对象的数据库里的信息的时候才进行Sql操作。
类级别检索:
注意:
1.类级别检索时, 当查询方法为get方法时,类级别的懒加载是对get方法无效的。
2.查询的对象,并不是被查询对象的本生,而是Hibernate动态生成的一个代理类,并且继承了被查询对象。 只有延迟检索才会产生代理,立即检索是不会产生代理类的。
Customer类:(get和set省略)
public class Customer {
private Integer id;
private String fname;
private String lname;
private Integer age;
private Date birthday;
private boolean married;
private byte[] photo;
private String description;
private Set<Order> set = new HashSet<Order>();
}
Customer.hbm.xml:
<?xml version="1.0"?>
<!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.xxc.domain.Customer" table="Customers" lazy="true">
<id name="id" column="id" type="integer">
<generator class="native"></generator>
</id>
<property name="name" column="name" type="string" length="20" access="property"/>
<property name="birthday" column="birthday" type="date"/>
<property name="age" column="age" type="integer" length="20"/>
<property name="description" column="description" type="text" />
<property name="married">
<column name="married" sql-type="int(20)"></column>
</property>
<property name="photo">
<!-- property表的column属性和子元素column是互斥的,只能用其一 -->
<column name="photo" sql-type="longblob"></column>
</property>
</class>
</hibernate-mapping>
Order类:(get和set省略)
public class Order {
private Integer id;
private String orderNumber;
private float price;
/* 建立从Order到Customer之间多对一关联关系 */
private Customer customer ;
}
Order.hbm.xml:
<?xml version="1.0"?>
<!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.xxc.domain.Order" table="Orders" lazy="true">
<id name="id" column="id" type="integer">
<generator class="native"></generator>
</id>
<property name="orderNumber" column="orderNumber" type="string" length="20"/>
<property name="price" column="price" type="float"/>
<!-- 映射从Order到Customer之间多对一关联关系 -->
<many-to-one name="customer" class="com.xxc.domain.Customer" column="cid" cascade="save-update" />
</class>
</hibernate-mapping>
测试类:
package com.xxc.app;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.BeforeClass;
import org.junit.Test;
import com.xxc.domain.Customer;
import com.xxc.domain.Order;
public class App {
private static SessionFactory sf = null;
@BeforeClass
public static void initialize(){
Configuration config = new Configuration();
/* 也可以写成这样的形式
* sf = config.addClass(Customer.class).addClass(Order.class).buildSessionFactory();
*/
config.addClass(Customer.class);
config.addClass(Order.class);
sf = config.buildSessionFactory();
}
@Test
public void iniDB(){
Session s = sf.openSession();
Transaction t = s.beginTransaction();
Customer c = new Customer();
c.setAge(20);
s.save(c);
Order o = null;
for(int i = 0 ; i < 10 ; i++){
o = new Order();
o.setOrderNumber("No:"+i);
o.setPrice(500f);
o.setCustomer(c);
c.getSet().add(o);
s.save(o);
}
t.commit();
s.close();
}
@Test
public void testJianSuoCeLue(){
Session s = sf.openSession();
Transaction t = s.beginTransaction();
Order o= (Order) s.load(Order.class, 1);
//Order o = (Order) s.get(Order.class, 1); 当查询方法为get方法时,类级别的懒加载是对get方法无效的。
/*
* 那么既然当执行o.getClass()和o.getId()时,都没有执行sql语句,那为何o是有值的?(反之o.getClass()肯定要抛NullPoiontException)
* 从打印o.getClass()可看出,其实o并不是Order类,而是Order_$$_javassist_1
* 这个代理类是由Hibernate动态的创建一个代理类去继承Order而来的,这个代理类可以监测到session是否关闭
*/
System.out.println(o.getClass());//当class标签lazy=true这句话还没执行sql,因为获取这个信息不需要进行数据库查询后才能得出
System.out.println(o.getId());//当class标签lazy=true这句话还没执行sql,因为id在你指定查询条件的时候,load第二个参数已经手动指定了,也不需要查询数据库才能得出结果的。
// System.out.println(o.getPrice());//当class标签lazy=true只有执行到这句话的时候,才会进行sql操作,因为这个信息只有查询数据库才能获取。
//手动的进行代理类的初始化工作
if(! Hibernate.isInitialized(o)){//判断指定类是否初始化了
Hibernate.initialize(o);//若没有,则进行初始化,其实就是进行数据库的查询操作,操作此对象的数据库信息
}
t.commit();
s.close();
System.out.println(o.getPrice());//假如将查询对象的操作放在这里
/* 会报以下异常:没有session,不能初始化代理
* LazyInitializationException:42 - could not initialize proxy - no Session
*/
}
}