`

[转]hibernate中的 bag--解释的太好了.

阅读更多

Bag是集合,与Set不同的是,Bag允许重复的元素,

在Java的标准API中并没有提供Bag容器,Hibernate提供自己的Bag实现,允许您将List映射为Bag。

您可以如下定义User类别,其中的List成员将被用作Bag来使用,而不管物件在List容器中的顺序:

  • User.java
package onlyfun.caterpillar;

import java.util.List;

public class User {
private Integer id;
private String name;
private List items;

// 必须要有一个预设的建构方法
// 以使得Hibernate可以使用Constructor.newInstance()建立物件
public User() {}

public Integer getId() {
return id;
}

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

public String getName() {
return name;
}

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

public List getItems() {
return items;
}

public void setItems(List items) {
this.items = items;
}

public void addItem(String item) {
items.add(item);
}

public void removeItem(String name) {
items.remove(name);
}
}

最简单的Bag映射是使用<bag>标签,在这之前,假设您如下建立表格:
CREATE TABLE user (
    id INT(11) NOT NULL auto_increment PRIMARY KEY,
    name VARCHAR(100) NOT NULL default ''
);

CREATE TABLE item (
    id INT(11) NOT NULL,
    name VARCHAR(100) NOT NULL
);

接着定义映射文件,如下所示:

  • User.hbm.xml
java 代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <!DOCTYPE hibernate-mapping  PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
  3. <hibernate-mapping>   
  4.     <class name="onlyfun.caterpillar.User" table="user">   
  5.         <id name="id" column="id" type="java.lang.Integer">   
  6.             <generator class="native" />   
  7.         </id>   
  8.         <property name="name" column="name" type="java.lang.String" />   
  9.         <bag name="items" table="item">   
  10.             <key column="id" />   
  11.             <element column="name" type="java.lang.String" />   
  12.         </bag>   
  13.     </class>   
  14. </hibernate-mapping>  

假设您如下储存物件:
User user1 = new User();
user1.setItems(new ArrayList());
user1.setName("caterpillar");
user1.addItem("Java Gossip");
user1.addItem("Java Gossip");
user1.addItem("Caxxx A80");
       
User user2 = new User();
user2.setItems(new ArrayList());
user2.setName("momor");
user2.addItem("Snoppy world");       
       
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user1);
session.save(user2);
tx.commit();
session.close();

则资料库中会有如下的资料:

mysql> select * from user;
+----+-------------+
| id    | name        |
+----+-------------+
|  1    | caterpillar |
|  2    | momor       |
+----+-------------+
2 rows in set (0.00 sec)

mysql> select * from item;
+----+--------------------+
| id    | name                 |
+----+-------------------+
|  1    | Java Gossip     |
|  1    | Java Gossip     |
|  1    | Caxxx A80        |
|  2    | Snoppy world |
+----+-------------------+
4 rows in set (0.00 sec)


您可以如下更新资料:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.load(User.class, new Integer(1));
user.removeItem("Java Gossip");
tx.commit();
session.close();

然而注意观察在更新资料时所使用的SQL:
Hibernate: delete from item where id=?
Hibernate: insert into item (id, name) values (?, ?)
Hibernate: insert into item (id, name) values (?, ?)

由于Bag的资料允许重复,当必须更新资料时,无法确定要更新的是哪一笔资料,因而采取的方式是删除集合物件对应的所有资料,然后重新将集合物件中的资料写入资料库,显然的这种作法相当的没有效率。

作为Bag的一种扩充,Hibernate提供idbag,藉由在定义Bag映射时加上"collection-id",让Hibernate可以直接确定所要更新的资料,提高资料库操作的效率,您可以先如下建立表格:
CREATE TABLE user (
    id INT(11) NOT NULL auto_increment PRIMARY KEY,
    name VARCHAR(100) NOT NULL default ''
);

CREATE TABLE item (
    cid CHAR(32) NOT NULL,
    id INT(11) NOT NULL,
    name VARCHAR(100) NOT NULL
);

其中item表格的cid就用于资料更新时定位之用,接着在映射文件中使用<idbag>标签加以定义:
  • User.hbm.xml
xml 代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE hibernate-mapping  PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  3. <hibernate-mapping>  
  4.     <class name="onlyfun.caterpillar.User" table="user">  
  5.         <id name="id" column="id" type="java.lang.Integer">  
  6.             <generator class="native" />  
  7.         </id>  
  8.         <property name="name" column="name" type="java.lang.String" />  
  9.         <idbag name="items" table="item">  
  10.             <collection-id column="cid" type="java.lang.String">  
  11.                 <generator class="uuid.hex" />  
  12.             </collection-id>  
  13.             <key column="id" />  
  14.             <element column="name" type="java.lang.String" />  
  15.         </idbag>  
  16.     </class>  
  17. </hibernate-mapping>  

使用上面用过的程式片段来储存物件的话,资料库中会有如下的资料:
mysql> select * from user;
+----+-------------+
| id    | name        |
+----+-------------+
|  1    | caterpillar |
|  2    | momor      |
+----+-------------+
2 rows in set (0.00 sec)

mysql> select * from item;
+------------------------------------------------+----+--------------------+
| cid                                                            | id   | name                  |
+------------------------------------------------+----+--------------------+
| 297eba61056726030105672605df0001 |  1   | Java Gossip      |
| 297eba61056726030105672605df0002 |  1   | Java Gossip      |
| 297eba61056726030105672605df0003 |  1   | Caxxx A80         |
| 297eba61056726030105672605df0004 |  2   | Snoppy world  |
+------------------------------------------------+----+-------------------+
4 rows in set (0.00 sec)


如果使用上面提到过的程式片段来更新物件的话,则实际上Hibernate会使用以下的SQL来进行更新:
Hibernate: delete from item where cid=?

这一次并不是整个删除集合中的资料,而是直接藉由cid来确定所要更新的资料,比起只使用Bag,idbag的效率好了许多。
分享到:
评论

相关推荐

    hibernate bag 集合映射

    标题中的“hibernate bag 集合映射”指的是Hibernate框架中的一种关系映射机制。Hibernate是一个流行的Java ORM(对象关系映射)框架,它允许开发者将数据库表与Java类进行映射,使得在处理数据库操作时可以使用面向...

    Hibernate one-to-many / many-to-one关系映射

    在Java的持久化框架Hibernate中,关系映射是数据库对象之间的关联方式,它允许我们将复杂的数据库结构映射到Java对象上。"Hibernate one-to-many / many-to-one关系映射"是两个基本的关系类型,用于表示实体间的关联...

    Hibernate-Spring-Struts面试题目

    在Hibernate中,可以通过注解或XML配置来实现对象属性和集合的延迟加载。 【类间关系映射】 Hibernate 支持多种对象关系映射,如一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多...

    Hibernate+中文文档

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    Hibernate中文详细学习文档

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    HibernateAPI中文版.chm

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    @hibernate Tag Reference

    本文档旨在提供一个全面的@hibernate Tag参考指南,帮助开发人员更好地理解和使用这些标签。 #### 一、@hibernate Tag for Class Level 在类级别上应用@hibernate Tag可以定义持久化类的属性和行为。 ##### 1.1 @...

    Hibernate 中文 html 帮助文档

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    hibernate3.2中文文档(chm格式)

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    JAVA培训-HIBERNATE的集合映射.doc

    为了更好地解释集合映射的概念,我们首先定义两个实体类:`Customer`类与`Order`类。这两个类分别对应数据库中的`customer`表和`orders`表,并且存在一个典型的“一对多”关系。具体定义如下: 1. **Customer 类** ...

    Hibernate4(关系映射-事务-原理-性能和二级缓存-最佳实践)

    在Hibernate中配置二级缓存,需要在映射文件中使用元素,以及选择合适的缓存提供者,如EhCache、OSCache等。 6. 最佳实践:最佳实践是指在使用Hibernate时推荐的一些开发习惯和技术选择。例如,应该尽量使用双向...

    commons.collections-3.2.1和commons-beanutils-1.9.2和commons.collections-3.2.1

    此外,它们也常用于数据持久化操作,比如在Hibernate或MyBatis中,对查询结果进行转换和处理。 总的来说,Commons Collections和Apache BeanUtils是Java开发中不可或缺的工具库,它们大大提高了代码的可读性和可...

    hibernate。hbm.xml配置详解

    在 Hibernate 中,`hbm.xml` 文件是用于定义对象与数据库表之间映射的元数据文件。这篇文档将深入解析 `hbm.xml` 配置的各个方面。 ### 1. `hbm.xml` 文件结构 `hbm.xml` 文件的开头通常包含 XML 声明和 DTD 引用...

    hibernate3.04中文文档.chm

    Bag和list是反向集合类中效率最高的 20.5.4. 一次性删除(One shot delete) 20.6. 监测性能(Monitoring performance) 20.6.1. 监测SessionFactory 20.6.2. 数据记录(Metrics) 21. 工具箱指南 21.1....

    Hibernate中文API大全

    你必须作出一个选择,要么在组合元素中使用不能为空的属性,要么选择使用,,&lt;bag&gt; 或者 而不是 。 组合元素有个特别的用法是它可以包含一个&lt;many-to-one&gt;元素。类似这样的映射允许你将一个many-to-many关联表映射为...

    hibernate map 集合映射

    在Java的持久化框架Hibernate中,集合映射是将数据库中的表关系映射到对象的集合属性上,以便更好地管理和操作数据。这篇文章将深入探讨Hibernate中的集合映射机制,包括其基本概念、类型以及如何在实际开发中进行...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     14.2 映射Bag(包)  14.3 映射List(列表)  14.4 映射Map  14.5 对集合排序  14.5.1 在数据库中对集合排序  14.5.2 在内存中对集合排序  14.6 映射组件类型集合  14.7 小结  14.8 思考题 第15章 映射...

    最全Hibernate 参考文档

    Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One shot delete) 19.6. 监测性能(Monitoring performance) 19.6.1. 监测SessionFactory 19.6.2. 数据记录(Metrics) 20. 工具箱指南 20.1. ...

    hibernate-07-o2m-bidirectional.rar_Java编程_Java_

    2. **配置映射文件**:在Hibernate的XML映射文件中,为这两个实体类定义对应的`&lt;class&gt;`标签,并使用`&lt;bag&gt;`或`&lt;set&gt;`标签来表示多的一方(如`Order`),使用`&lt;one-to-many&gt;`标签指定关联的单一方(如`User`)。...

Global site tag (gtag.js) - Google Analytics