您的位置:首页 > Web前端

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

2011-07-20 14:27 447 查看
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条记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: