Hibernate检索策略之类级别检索策略

来源:互联网 发布:dev c for mac 编辑:程序博客网 时间:2024/05/29 11:49

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;@BeforeClasspublic 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();}@Testpublic 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();}@Testpublic 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 */}}


原创粉丝点击