题目:设计一个用户类,基本属性有id,name,messages,messages是一个存放用户信息的集合(每条信息不重复),并通过hibernate完成保存操作。
由于第一范式(关系模式R的所有属性都是不可分的基本数据项),我们有时需要额外的表来存储数据,hibernate提供了集合映射来解决这一问题。
显然这里无法简单通过一张表来实现,需要一张额外的表来存放每一个user的message,这张表结构大概是这样的要有[user_id][user_message]这两列.
- User.java
public class User {
private int id;
private String name;
private Set<String> messageSet=new HashSet<String>();
//getter() and setter()
}
- User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibernate_collection" >
<class name="User" table="t_user">
<id name="id" >
<generator class="native"/>
</id>
<property name="name" type="string" column="name" length="20"/>
<set name="messageSet" table="t_user_messageSet">
<key column="userId"></key>
<element type="string" column="message"></element>
</set>
</class>
</hibernate-mapping>
由于信息是不重复的所以这里使用set集合,对应的mapping就也是set。
其实还是对应实体类来写,只不过这里不是普通属性,而一个集合,集合在数据库中就是一张表,所以我们这里使用<set>
标签而不是<property>
。
-
<set name="messageSet" table="t_user_messageSet">
name:实体类中的属性
table:对应数数据库中的表 -
<key column="userId"></key>
<key>:外键
column:数据库中表的外键列的列名 -
<element type="string" column="message"></element>
<element>:数据库中表的普通列
type:列在hibernate中对应的类型
column:类名
- 测试类
public class test {
@Test
public void testSave(){
Configuration cfg=new Configuration();
cfg.configure().addClass(User.class);
SessionFactory sessionFactory=cfg.buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
User user=new User();
user.setName("user1");
user.setMessageSet(new TreeSet<String>());
user.getMessageSet().add("message1");
user.getMessageSet().add("message2");
session.save(user);
session.getTransaction().commit();
session.close();
}
}
结果图
- 其他
hibernate还提供<list>,<bag>,<map>等集合标签
1.使用hashset实现set时,集合是无序不重复的
2.使用ArrayList实现List时,集合是有序可重复的
3.使用ArrayList实现bag时,集合是无序可重复的
4.使用HashMap实现map时,key-value形式的键值对
对于有序集合最减少增删操作比较好,其实主要还是看你使用什么实现集合接口。