`

[转]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和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 中文 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. ...

    hibernate bag 集合映射

    NULL 博文链接:https://lijunabc.iteye.com/blog/443353

    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_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教程

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

    hibernate 体系结构与配置 参考文档(html)

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    Hibernate3+中文参考文档

    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是反向集合类中效率最高的 14.1.4. 一次性删除(One shot delete) 14.2. 用于延迟装载的代理 14.3. 第二层缓存(The Second Level Cache)s 14.3.1. 对映射(Mapping)缓冲 14.3.2. 策略:只读...

    hibernate 框架详解

    1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class ...

    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是反向集合类中效率最高的 14.1.4. 一次性删除(One shot delete) 14.2. 用于延迟装载的代理 14.3. 第二层缓存(The Second Level Cache)s 14.3.1. 对映射(Mapping)缓冲 14.3.2. 策略:只读...

    Hibernate常见集合映射(Set,List_Array,Map,Bag)

    Hibernate常见集合映射(Set,List_Array,Map,Bag)

    Hibernate实战(第2版 中文高清版)

     10.1.2 Hibernate应用程序中的事务   10.1.3 使用Java Persistence的事务   10.2 控制并发访问   10.2.1 理解数据库级并发   10.2.2 乐观并发控制   10.2.3 获得额外的隔离性保证   10.3 非事务数据...

Global site tag (gtag.js) - Google Analytics