前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hibernate 中集合对象的抓取策略(Fetching strategies)

Hibernate 中集合对象的抓取策略(Fetching strategies)

作者头像
Hongten
发布2018-09-18 09:53:38
3850
发布2018-09-18 09:53:38
举报
文章被收录于专栏:HongtenHongten

Product.java

代码;

package com.b510.examples;

/**  * Product entity. @author MyEclipse Persistence Tools  */

public class Product implements java.io.Serializable {

 private static final long serialVersionUID = -1546206493725028472L;  private Integer id;  private Category category;  private String name;  private String price;  private String descripton;

 public Product() {  }

 public Integer getId() {   return this.id;  }

 public void setId(Integer id) {   this.id = id;  }

 public Category getCategory() {   return this.category;  }

 public void setCategory(Category category) {   this.category = category;  }

 public String getName() {   return this.name;  }

 public void setName(String name) {   this.name = name;  }

 public String getPrice() {   return this.price;  }

 public void setPrice(String price) {   this.price = price;  }

 public String getDescripton() {   return this.descripton;  }

 public void setDescripton(String descripton) {   this.descripton = descripton;  }

}

Category.java

代码:

package com.b510.examples;

import java.util.HashSet; import java.util.Set;

public class Category implements java.io.Serializable {

 private static final long serialVersionUID = 3240281547213597385L;  private Integer id;  private String name;  private String description;  private Set products = new HashSet(0);

 public Category() {  }

 public Integer getId() {   return this.id;  }

 public void setId(Integer id) {   this.id = id;  }

 public String getName() {   return this.name;  }

 public void setName(String name) {   this.name = name;  }

 public String getDescription() {   return this.description;  }

 public void setDescription(String description) {   this.description = description;  }

 public Set getProducts() {   return this.products;  }

 public void setProducts(Set products) {   this.products = products;  }

}

Product.hbm.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"> <!--     Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping>     <class name="com.b510.examples.Product" table="product" catalog="users">         <id name="id" type="java.lang.Integer">             <column name="id" />             <generator class="increment" />         </id>         <many-to-one name="category" class="com.b510.examples.Category" fetch="select">             <column name="category_id" />         </many-to-one>         <property name="name" type="java.lang.String">             <column name="name" length="500" />         </property>         <property name="price" type="java.lang.String">             <column name="price" length="10" />         </property>         <property name="descripton" type="java.lang.String">             <column name="descripton" length="500" />         </property>     </class> </hibernate-mapping>

Category.hbm.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"> <!--     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" >             <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();    for(Product p:products){     System.out.println(p.getName());    }   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=? java SE应用程序设计 这里我们看到 的是,我们在读取一个集合对象的 时候,hibernate用了一条selelct语句;

1、查询抓取(Select fetching)

修改:Category.hbm.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"> <!--     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" fetch="select">             <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();    for(Product p:products){     System.out.println(p.getName());    }   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=? java SE应用程序设计 这种方法是查询抓取,他是hibernate默认值,所以我们会看到和上面的运行效果一摸一样。

测试代码二:

HibernateTest.java

代码;

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

import java.util.Set;

import org.hibernate.Query; 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();  Query query=session.createQuery("select c from Category c inner join fetch c.products where c.id=?");   query.setInteger(0, 1);   Category category=(Category)query.uniqueResult();   System.out.println("id:"+category.getId()+"  ,name:"+category.getName()+", description:"+category.getDescription());   Set<Product> products=category.getProducts();    for(Product p:products){     System.out.println(p.getName());    }   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_,         products1_.id as id0_1_,         category0_.name as name1_0_,         category0_.description as descript3_1_0_,         products1_.category_id as category2_0_1_,         products1_.name as name0_1_,         products1_.price as price0_1_,         products1_.descripton as descripton0_1_,         products1_.category_id as category2_0__,         products1_.id as id0__     from         users.category category0_     inner join         users.product products1_             on category0_.id=products1_.category_id     where         category0_.id=? id:1  ,name:java, description:java好啊 java SE应用程序设计

我们发现现在hibernate只是用了一个select语句。这是我们通过hql语句重载底层设置的抓取策略

hql的优先级很好。尽管你我们在配置文件中设置了fetch=“select”,就是说hibernate要用两个selelct语句

去执行这样的行为,但是,我们在hql语句中设置了急迫内连接查询,这样hibernate就必须只用一条select语句去查询

这样就等于把我们底层设置进行了重载,或者说是覆盖。

2、子查询抓取(Subselect fetching)

 Category.hbm.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"> <!--     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" fetch="subselect">             <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.Iterator; import java.util.List; import java.util.Set;

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

/**  *  * @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();   Transaction tx = session.beginTransaction();

List categorys = session.createQuery("from Category").list();   for (Iterator<Category> it = categorys.iterator(); it.hasNext();) {    Category category = it.next();    System.out.println("id:" + category.getId() + "  ,name:"      + category.getName() + ", description:"      + category.getDescription());    for (Iterator<Product> it2 = category.getProducts().iterator(); it2      .hasNext();) {     Product p = it2.next();     System.out.println(p.getName());    }   }   tx.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_,         category0_.name as name1_,         category0_.description as descript3_1_     from         users.category category0_ 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 in ( select                 category0_.id             from                 users.category category0_         ) java SE应用程序设计 id:2  ,name:Hibernate, description:Hibernate好啊 java WEB开发与实战

我们看到,下面的selelct语句中又嵌套了一个select语句

3、连接抓取(Join fetching)

Category.hbm.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"> <!--     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" fetch="join">             <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.Iterator; import java.util.List;

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

/**  *  * @author XHW  *  * @date 2011-7-18  *  */ public class HibernateTest {  public static void main(String[] args) {   new HibernateTest().example();  }

 public void example(){   Session session =HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();   Transaction tx=session.beginTransaction();   Category category=(Category)session.get(Category.class, 1);   System.out.println("id:" + category.getId() + "  ,name:"     + category.getName() + ", description:"     + category.getDescription());   Iterator<Product> it=category.getProducts().iterator();   Product p=null;   while(it.hasNext()){    p=it.next();    System.out.println(p.getName());   }   tx.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_1_,         category0_.name as name1_1_,         category0_.description as descript3_1_1_,         products1_.category_id as category2_3_,         products1_.id as id3_,         products1_.id as id0_0_,         products1_.category_id as category2_0_0_,         products1_.name as name0_0_,         products1_.price as price0_0_,         products1_.descripton as descripton0_0_     from         users.category category0_    left outer join         users.product products1_             on category0_.id=products1_.category_id     where         category0_.id=? id:1  ,name:java, description:java好啊 java SE应用程序设计

4、批量抓取(Batch fetching)

 Category.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"> <!--     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" batch-size="3">             <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.Iterator; import java.util.List;

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

/**  *  * @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();   Transaction tx = session.beginTransaction();

  List<Category> categorys = session.createQuery("from Category").list();   for(Category category:categorys){    System.out.println(category.getProducts());   }     tx.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_,         category0_.name as name1_,         category0_.description as descript3_1_     from         users.category category0_ 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 in (   ?, ?, ?         ) [com.b510.examples.Product@d7b7d9, com.b510.examples.Product@93df2c, com.b510.examples.Product@3a1834, com.b510.examples.Product@190a0d6, com.b510.examples.Product@2f729e, com.b510.examples.Product@10deb5f, com.b510.examples.Product@b1cd0] [com.b510.examples.Product@18488ef] 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 in (       ?, ?, ?         ) [] 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 in (   ?, ?         ) batch-size="3"所以查询的时候是一次查询3条记录。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-07-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档