当前位置: 亚洲城ca88 > ca88 > 正文

Hibernate延迟加载,Hibernnate延迟加载战略

时间:2019-04-22 15:39来源:ca88
public static void main(String[] args) {   DeptEntity dept = getDept("402882e762ae888d0162ae888e420000"); 推迟加载在Hibernate中是暗许延迟加载; Hibernnate延迟加载计策(这么详细你还看不懂),hibernnate延迟 旷

public static void main(String[] args) {
 
  DeptEntity dept = getDept("402882e762ae888d0162ae888e420000");

推迟加载在Hibernate中是暗许延迟加载;

Hibernnate延迟加载计策(这么详细你还看不懂),hibernnate延迟

旷日持久未有当真写过博客了,今日就完美的写一篇吧!!!!!!!!!

当Hibernate 从数据库中加载有些对象(举个例子:Dept对象)时,假如同时自动加载全数的关系的某部对象(比方:Emp对象),而先后实际上只是须求拜访Dept对象,那么这么些涉嫌的Emp对象就白白浪费了许多内部存款和储蓄器空间。发生那种情状的由来是:正是即时加载的主题素材。

一.什么是及时加载呢?

Hibernate 查询 Dept 对象时,马上加载并加载与之提到的Emp对象,那种查询攻略称为 立时加载。

旋即加载存在两大不足:

1.select 语句的数目太多,要求反复地走访数据库,会潜移默化查询性能。

贰.在应用程序只须要拜访Dept对象时,而不须要访问Emp对象的场所,加载Emp对象完全是剩下的操作,那一个剩余的Emp对象就白白的浪费了过多内部存储器空间。

 

那正是说我们务供给搞定这些难点,所以就要聊到了“延迟加载”的文化了,延迟加载战略能防止加载应用程序不必要拜访的涉及对象,以优化查询性能。

然则咱们要明白有各个查询计谋,接下去我们就一同来分析每壹种查询计谋的加载难点。

先是种:类品级的查询计策

图片 1

类等第可选的加载计策包罗登时加载和延迟加载,私下认可是延迟加载,倘使,<class>成分的lazy的性质为true,表示接纳延迟加载;假若lazy 属性 为 false,表示选择当下加载。

我们今日以代码来分解是最棒的办法。

1.及时加载计策

我们在Dept.hbm.xml文件中 加 lazy=“false”  属性,即可。

图片 2

表结构:

 图片 3

测试代码:

    Session session = HibernateUtil.currentSession();

        session.beginTransaction();

        Dept dept = (Dept)session.load(Dept.class, 1);

        System.out.println("部门名称" dept.getdName());

        System.out.println("===================");

        Dept dept2 = (Dept)session.load(Dept.class, 1);

        System.out.println("部门名称" dept2.getdName());

        session.getTransaction().commit();

        HibernateUtil.closeSessio();

测试结果:

 图片 4

大家精晓使用Load方法加载的是代理对象,只会在质量里保存三个OID,可是只要在Dept映射文件中安插了类等第的lazy为false就意味着加载该目的时即时加载,也正是随即搜索1遍数据库,发出了一条sql语句。

2.延迟加载

类级其余暗中同意加载战术便是延迟加载。在在Dept.hbm.xml文件中 ,以下三种办法都代表延迟加载战略。

 图片 5

或是

 图片 6

若果程序加载1个持久化对象的目标是为着访问它的个性,那是大家得以行使当下加载,可是只要程序加载一个持久化对象的目标是为了获得它的引用,那是我们能够使用延迟加载,无须访问Dept对象的脾性。

看例子:

   

   Dept dept = (Dept)session.load(Dept.class, 1);

        System.out.println("部门名称" dept.getdName());

        Employee emp=new Employee();

        emp.setEname("李四");

        emp.setDept(dept);

        session.save(emp);

 

那段代码向数据库保存了 四个Employee 对象,它与已经存在的贰个Dept持久化对象关联。倘使在Dept 类等第选择延迟加载,则 session.load()方法不会进行访问DEPT 表的select 语句,只回去多个Dept的代理对象,它的deptNo的属性值为壹,其他属性都为NULL。session.save()方法试行的sql语句:

 图片 7

由此当,<class>成分的lazy属性为true时,会潜移默化session.load()方法的种种运营时作为。比如表达:

1.尽管加载的Dept对象在数据库中不设有时,不会抛出1贰分,唯有运营dept.getxxx()时,才会抛出非常。

测试代码:

    Session session = HibernateUtil.currentSession();

        session.beginTransaction();

        Dept dept = (Dept)session.load(Dept.class, 3);

        System.out.println("部门名称" dept.getdName());

        Employee emp=new Employee();

        emp.setEname("李四");

        emp.setDept(dept);

        session.save(emp);

 

当 deptNo为三不存在时,会抛出以下至极:

 图片 8

2.只要在在整个Session范围内,应用程序未有访问过的Dept对象,那么Dept代理类的实例一贯不会被初阶化,Hibernater 不会推行此外的select语句。以下代码试图在关门Session后走访的Dept游离对象:

测试代码:

Session session = HibernateUtil.currentSession();

        session.beginTransaction();

        Dept dept = (Dept)session.load(Dept.class, 3);

        HibernateUtil.closeSessio();

        System.out.println("部门名称" dept.getdName());

        session.getTransaction().commit();

        HibernateUtil.closeSessio();

 

从代码中我们得以看来,session被提前关闭,所以dept引用的Dept代理类的实例在Session范围内始终未有被开端化,所以当实施到  System.out.println("部门名称" dept.getdName())时,会抛出以下极度:

图片 9

 

 

有鉴于此,Dept代理类的实例只有在脚下的Session范围内才能被开头化。

3.import org.hibernate.Initialized()静态方法,用于在Session范围内显式初叶化代理类实例,isInitialized()方法用于剖断代理类实例是或不是业已被伊始化。

代码:

Dept dept = (Dept)session.load(Dept.class, 1);

if(!Hibernate.isInitialized(dept)){

Hibernate.initialize(dept);

HibernateUtil.closeSessio();

System.out.println("部门名称" dept.getdName());

}

 

以上代码在Session范围内经过Hibernate 类的Initialized()方法显式初步化了Dept代理类实例,因而关闭Session关闭后,能够健康访问Dept的游离对象。

四.当顺序访问代理类实例的getDeptNo()方法时,不会触发Hibernate 伊始化 代理类实例的一言一动。举个例子:

代码:

Dept dept = (Dept)session.load(Dept.class, 1);

      System.out.println("编号:"  dept.getDeptNo());

HibernateUtil.closeSessio();

System.out.println("部门名称" dept.getdName());

 

当程序访问dept.getDeptNo()方法时,该办法直接回到Dept代理类的实例OID值,无须查询数据库。由于变量dept始终引用的是绝非伊始化的Dept代理类的实例,由此当Session关闭后再进行dept.getdName()方法,会抛出以下非凡。

 图片 10

唯独值得我们注意的是:不管Dept.hbm.xml文件的<class>成分的习性是true依旧false,Session 的get方法及Query对象的list方法在Dept类等级总是接纳即时加载战略。比方表达:

一.Session的get方法总是立刻到数据库中询问Dept查询对象,纵然在数据库中不存在对应的数目,就会回来NULL,举例:

代码:

 

Session session = HibernateUtil.currentSession();
        session.beginTransaction();
        Dept dept = (Dept)session.get(Dept.class, 3);
        System.out.println(dept);

 

结果:

图片 11

 

因此可见,get方法长久不会实行Dept的代理类实例。

二.Query的list方法总是马上到数据库中查询Dept对象

 

代码:

List<Dept> query = session.createQuery("from Dept").list();
        for (Dept dept : query) {
            System.out.println(dept.getdName());
        }

结果:

图片 12

 

到了这边,算是把第三种类级其他查询计策写的好些个了。

其次种:1对多和多对一关乎的查询计谋

图片 13

累加2个小知识点:

0壹.一对多恐怕多对多物色计策由lazy和fetch共同鲜明

 

02.fetch取值

    Join:急迫    Lazy:决定涉及对象起先化时机

左外连接

    Select:多条轻易SQL(暗许值)

    Subselect:子查询

03.fetch和lazy组合

  解析:fetch=”join” lazy会被忽视,热切左外连接的立时寻找

        Fetch=”s    Fetch:决定SQL语句创设方式

elect” lazy=”false”  多条轻巧SQL立即找寻

        Fetch=”select” lazy=”true”  多条语句延迟检索

        Fetch=”select” lazy=”extra”  多条语句及其懒惰检索

        Fetch=”subselect” lazy=”false”  子查询立时寻觅

        Fetch=”subselect” lazy=”true”  子查询延迟检索

        Fetch=”subselect” lazy=”extra”  子查询及其懒惰检索

Extra:及其懒惰,唯有访问集合对象的质量时才会加载,访问会集本人的性质时(举个例子,群集大小,生成count),不会立时加载。

注意:query的list()会忽视映射文件配置的左外连接查询,fetch,此时lazy属性重新生效。

 

 

在炫耀文件中,用<SET>成分来安排1对多涉及及多对1涉嫌关系的加载计策。Dept.hbm.xml文件中的一下代码用于配置Dept和Employee类的壹对多涉及关系:

  <!-- 双向     cascade:级联     inverse:反转 -->
           <!--set表明Dept类的emps属性为set集合类型  -->
           <!--order-by 对集合排序  order-by="dName asc   order-by="dName desc-->
           <set name="emps" inverse="true" lazy="true">
           <!--employee表的外键 deptNo  -->
           <key column="deptNo"></key>
           <!--一对多    class 属性设定与所关联的持久化类 为employee -->
           <one-to-many class="Employee"/>
           </set>

 

那边的<set>元素有lazy属性,主要取决于emps集合被开首化的空子,到底是在加载Dept对象时就被开端化,如故在程序访问emps集结时被开始化。

1.立即加载

Dept.hbm.xml的配备文件:

图片 14

测试代码:

        Dept dept = (Dept)session.get(Dept.class, 1);
        System.out.println(dept.getdName());

结果:实践Session的get方法时,对于Dept对象采纳类级其余当下加载战略,对于Dept对象的emps集结(Dept关联全体的employee对象),接纳一对多涉及的马上加载战略。

图片 15

 

 从那几个结果我们能够见见,Hibernate加载了七个Dept对象和Employee对象,可是大家精晓多数景况下,不供给访问Employee对象,所以我们就得用了 延迟加载战略。

二.延迟加载

对此<set>成分,应该事先思量使用的私下认可延迟加载战略。

图片 16

 

测试代码:

    Dept dept = (Dept)session.get(Dept.class, 1);
        System.out.println(dept.getdName());

结果:

图片 17

很备受关注,只进行了一条sql语句,即唯有加载了Dept对象。

Session的get方法,重临的是Dept对象的emps属性引用三个从未被早先化的集合代理类实例。换句话说,此时的emps群集中从不存扬弃何Emp对象,唯有emps集结代理类实例被发轫化时,才回去数据库查询全数与Dept关联的Emp对象。

测试代码:

    Dept dept = (Dept)session.get(Dept.class, 1);
        System.out.println(dept.getdName());

        for (Employee emp : dept.getEmps()) {
            System.out.println(emp.getEname());
        }

结果:

图片 18

 

那么,Dept对象的emps属性引用的集纳代理类实例什么日期被开始化呢?主要不外乎以下二种情状:

0一.当应用程序第3遍访问它时,如调用 iterator(),size(),isEmpty(),或是 contains()方法时:

代码:

    Dept dept = (Dept)session.get(Dept.class, 1);
        Set<Employee> emp=dept.getEmps();
        System.out.println(dept.getdName());

        Iterator<Employee> itee=emp.iterator();//emps被初始化

0二.透过hibernate的静态方法initialize()来开端化它。

    Dept dept = (Dept)session.get(Dept.class, 1);
        Set<Employee> emp=dept.getEmps();
        System.out.println(dept.getdName());
        Hibernate.initialize(emp);//emps被初始化

三.进步延迟加载

lazy="extra"

计划如下:

 图片 19

增长延迟加载攻略能更进一步延迟Dept对象的emps集结代理类实例初叶化时机。当应用程序第2回访问emps属性的iterator()时,会招致emps集结代理类的实例早先化。不过当当应用程序第三次size(),isEmpty(),或是 contains()方法时,emps不会开始化emps群集代理实例。仅仅经过询问select语句须求消息。

测试代码:

Dept dept = (Dept)session.get(Dept.class, 1);
//不会伊始化emps集合代理类实例
int size = dept.getEmps().size();
System.out.println(size);

//会开始化emps集合代理类实例
Iterator<Employee> iterator = dept.getEmps().iterator();
System.out.println(iterator);

结果:

图片 20

当今是第几种:多对一关系的查询计谋

lazy=proxy

 Employee.hbm.xml中但自己安顿:

图片 21

一.延缓加载计策。

测试代码:

Employee em=(Employee) session.get(Employee.class, 21);//仅仅执行em对象的sql语句
        Dept dept = em.getDept();
        System.out.println(dept.getdName());//执行Dept对象

当Sesson实行get()方法时,仅仅即刻施行查询Employee对象的select语句。当Employee 对象引用Dept代理类实例,那几个代理类实例的IOD由Employee 表的DeptNo外键值决定。 当实行dept.getdName()时,hibernate 开端化Dept代理类实例,执行以下select语句到数据库中加载Dept对象。

结果:

图片 22

 

无代理延迟加载:

lazy="no-proxy" 

图片 23

测试代码:

        Employee em=(Employee) session.get(Employee.class, 21);//仅仅执行em对象的sql语句
        Dept dept = em.getDept();
        System.out.println(dept.getdName());//执行Dept对象

设若Employee对象的dept属性使用无代理延迟加载,即<many-to-many>成分的lazy属性为no-proxy,当试行get方法时,加载的Employee的dept属性为NULL,当施行到  em.getDept()时,将触发hibernate实践查询Dept 表的select 语句,从而加载Dept对象。

结果:

图片 24

显而易见,当lazy为proxy 时,能够延长延迟加载 Dept对象的日子,而当lazy属性为no-proxy时,则能够幸免使用由hibernate 提供的Dept代理类实例,使用hibernate 对先后 提供越来越透明的持久化服务。

当下加载:

lazy=“false”

图片 25

测试:

    Employee em=(Employee) session.get(Employee.class, 21);

结果:

图片 26

能够看来,推行了两条sql语句。 

Open Session In View 模式9

Open Session In View 形式的法力:

 Hibernate 允许对事关对象、属性实行延期加载,然而必须保障延迟加载的操作限于同2个Hibernate Session 范围之内实行。借使 Service层重临三个启用了推迟加载成效的园地对象给 Web 层,当 Web 层访问到这个急需延期加载的多少时,由于加载领域对象的 Hibernate Session 已经关门,这几个形成延迟加载数据的拜会格外。

在Java Web 应用中,日常供给调用ibernate API 获取到展现的某部要突显的有些对象并传给相应但的视图JSP, 并在JSP中从那几个目的导航到与之提到的目的或集合数据。那几个涉及对象或会集数据假诺是被延迟加载的,hibernate 就会抛出以下万分:

图片 27

这是因为在调用完hibernate完事后,Session 对象已经倒闭了。针对这几个主题素材,hibernate 社区提供了Open Session In View 方式 的化解方案!!

代码示例:

  //dept.getEmp()获得子表的记录集结
  System.out.println(dept.getEmp());

测试代码一:

HibernateUtil代码

 private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();
//私有的静态的配置对象
 private static Configuration configuration;
//私有的静态的工厂对象
 private final static SessionFactory sessionFactory;
 //静态代码块,负责给成员变量赋值
 static{
     configuration=new Configuration().configure();
     sessionFactory=configuration.buildSessionFactory();
 }
 //从SessionFactory  连接池            获取一个和当前thread bind session
 public static Session currentSession(){
    //2.返回当前的线程其对应的线程内部变量

      //sessionTL的get()方法根据当前线程再次回到其对应的线程内部变量,

     //也正是大家要求的Session,二十四线程景况下共享数据库连接是不安全的。

       //ThreadLocal保障了各个线程都有友好的Session.

     Session session=sessionTL.get();
     //如果当前线程是session 为空=null ,则打开一个新的Session
     if(session==null){
         //创建一个session对象
         session=sessionFactory.openSession();
         //保存该Sessioon对象到ThreadLocal中
         sessionTL.set(session);     
     } 
     return session;
 }
 //关闭Session
 public  static void closeSessio(){
     Session session=sessionTL.get();
     sessionTL.set(null);
     session.close();

 }

}

HibernateTest.java

biz层代码:

HibernateDao dao=new HibernateDao();
    public Object get(Class clazz,Serializable id){
           Object obj= dao.get(clazz, id);return obj;
    }

private static DeptEntity getDept(String did){
  Session session = sessionFactory.openSession();
  DeptEntity dept = (DeptEntity)session.get(DeptEntity.class, did);
  session.close();
  return dept;
}

代码:

dao层代码:

public Object get(Class clazz,Serializable id){
           Object result= HibernateUtils.currentSession().load(clazz, id);
           return result;
    }

filter层代码:

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {            
        Session session = null;
        Transaction tx = null;
        try {

            session = HibernateUtils.currentSession();
            System.out.println("filtert" session.hashCode());        
            tx = session.beginTransaction();                        
            // 执行请求处理链    双向过滤
            chain.doFilter(request, response);
            // 返回响应时,提交事务
            tx.commit();
        } catch (HibernateException e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            // 关闭session
            HibernateUtils.closeSession();
        }
    }

 

/**
 *
 */
package com.b510.examples;

过滤器在网址xml中的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>    
 <!-- 过滤器 -->
 <filter>
   <filter-name>openSessionInView</filter-name>
   <filter-class>cn.happy.filter.OpenSessionInViewFilter</filter-class>
 </filter>
 <filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

index.jsp页面包车型客车代码:

<body>
    <%
          HibernateBiz biz=new HibernateBiz();
        Emp emp=(Emp)biz.get(Emp.class,1);
      %>
     <%=emp.getEmpName() %>
  </body>

以此代码只是一个例证而已,你能够写别样的代码。那样就是完事了Open Session In View 情势。

再总计1回:

至于No Session的这一个主题材料,有了七种的化解方案:

方案一
在biz层 把load 改成get
方案二
/* if (!Hibernate.isInitialized(obj)) {
Hibernate.initialize(obj);
}*/
方案 三 :在 映射文件中 ,类品级 <set> 中丰硕 lazy =“false”
方案四: 在biz 层 先用一道 须要的UI使用 到的属性 ,然后在biz关闭
方案5:把实体类 改成 用 final 修饰,大家通晓,延迟加载的原因是 内部存款和储蓄器中 有代理对象 (其实是emp 类的子类),所以当大家设为 该类 不能够 有子类
方案六:Open Session In View 模式。

在上头都已经用代码做例子了,够清楚了的。

好久未有当真写过博客了,今日就不错的写一篇吧!!!!!!!!! 当 H...

运行结果:

import java.util.Set;

Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.javakc.hibernate.onetomany.entity.DeptEntity.emp, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:326)
at java.lang.String.valueOf(String.java:2827)
at java.io.PrintStream.println(PrintStream.java:771)
at com.javakc.hibernate.onetomany.action.TestAction.main(TestAction.java:74)

import org.hibernate.Session;

 

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }
 public void update(){
  Session session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Category category=(Category)session.get(Category.class, 1);
  System.out.println("id:" category.getId() "  ,name:" category.getName() ", description:" category.getDescription());
  
  Set<Product> products=category.getProducts();
  
  session.getTransaction().commit();  
 }
 
 
}

聚拢延迟加载开头化退步,不可能初步化贰个代理。就是聚众在非壹对一对象关系中,为了节省财富是默许延迟加载,而get方法又是非延迟加载,所以在实行完三回数据库查询后就实践session.close();关闭了session,而集合是延迟加载,在运用集结时再加载,此时session已经关闭,所以得不到代办。化解措施:能够在主表的hbm配置文件中,在<set>标签里设置lazy="false",会集就不推迟加载了,因而在实行get方法时,集结也博获得了,就不会产出延迟加载难题了。

运维结果:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name1_0_,
        category0_.description as descript3_1_0_
    from
        users.category category0_
    where
        category0_.id=?
id:1  ,name:java, description:java好啊

这边大家来看大家关心的是id,name和description属性,

虽说有:  Set<Product> products=category.getProducts(); 代码,即:不管理集结对象。可是大家只要的是:

  System.out.println("id:" category.getId() "  ,name:" category.getName() ", description:" category.getDescription());
输出的是id,name和description属性值,别的的大家随意,所以Hibernate用了lazy loading(延迟加载),带来的收益便是大家不关心的

数量,不用现在加载,当大家要用的时候,才去加载

测试代码二:

HibernateTest.java

代码:

/**
 *
 */
package com.b510.examples;

import java.util.Set;

import org.hibernate.Session;

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }
 public void update(){
  Session session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Category category=(Category)session.get(Category.class, 1);
  System.out.println("id:" category.getId() "  ,name:" category.getName() ", description:" category.getDescription());
  
  Set<Product> products=category.getProducts();
  for(Product product:products){
   System.out.println("ID:  " product.getId() "  name:" product.getName() " price: " product.getPrice());
  }  
  session.getTransaction().commit();  
 }
 
 
}

运作效果:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name1_0_,
        category0_.description as descript3_1_0_
    from
        users.category category0_
    where
        category0_.id=?
id:1  ,name:java, description:java好啊
Hibernate: 
    select
        products0_.category_id as category2_1_,
        products0_.id as id1_,
        products0_.id as id0_0_,
        products0_.category_id as category2_0_0_,
        products0_.name as name0_0_,
        products0_.price as price0_0_,
        products0_.descripton as descripton0_0_
    from
        users.product products0_

    where
        products0_.category_id=?
ID:  一  name:java SE应用程序设计 price: 7八.00
那边能够鲜明的报告大家,当我们要加载Set会集的时候,这时候才去加载,而地点的例子,表明的是我们不加载的时候

Hibernate就延期加载

裁撤延迟加载:

Category.hbm.xml

代码:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.b510.examples.Category" table="category" catalog="users">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="increment" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="500" />
        </property>
        <property name="description" type="java.lang.String">
            <column name="description" length="500" />
        </property>
        <set name="products" inverse="true" lazy="false">
            <key>
                <column name="category_id" />
            </key>
            <one-to-many class="com.b510.examples.Product" />
        </set>
    </class>
</hibernate-mapping>

测试代码:

HIbernateTest.java

代码:

/**
 *
 */
package com.b510.examples;

import java.util.Set;

import org.hibernate.Session;

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }
 public void update(){
  Session session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Category category=(Category)session.get(Category.class, 1);
  System.out.println("id:" category.getId() "  ,name:" category.getName() ", description:" category.getDescription());
  
  Set<Product> products=category.getProducts();
   
  session.getTransaction().commit();  
 }
 
 
}

运作效果:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name1_0_,
        category0_.description as descript3_1_0_
    from
        users.category category0_
    where
        category0_.id=?
Hibernate:
    select
        products0_.category_id as category2_1_,
        products0_.id as id1_,
        products0_.id as id0_0_,
        products0_.category_id as category2_0_0_,
        products0_.name as name0_0_,
        products0_.price as price0_0_,
        products0_.descripton as descripton0_0_
    from
        users.product products0_
    where
        products0_.category_id=?
id:1  ,name:java, description:java好啊
和测试代码一的运作结果相互相比较,大家会发觉,本次运营结果用了两条select语句。不过我们会发掘

其次条select语句,对于大家的需即使尚未供给的,他只有1个用处就是据有大家的程序实施时间。当然,

那是大家不愿意见到的结果。

相似意况下,Hibernate会暗中同意给大家设置延迟加载。lazy="true" ,那样会升高我们的连串质量,所以一般情状下,大家不会去

设置lazy="false",当然在特种的景况下,我们务供给撤消延迟加载的时候,大家就把lazy="false",就能够了

编辑:ca88 本文来源:Hibernate延迟加载,Hibernnate延迟加载战略

关键词: 亚洲城ca88