在编写数据库的时候我们常常会遇到实体中含有集合类型的情况,比如User实体,它除了会有id name gender等基础的属性之外,还有一个String的list用来存储他的地址,因为他可能有不知一处的地址,还有一个String的list来存他的订单。这时候我们在编写User类和与之对应的xml文件时该怎么写,以及最终的数据库有事怎么存储的呢?

下面我们来写程序测试一下:

1.打开eclipse,新建一个web dynamic project,src下新建包com.bean,在包内新建User.class,代码:

package com.bean;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
* @author Guest
*
*/
public class User {

private String name;
private String password;
private int gender;
private int userid;
private Set<String> orders = new HashSet<String>();
private List<String> address = new ArrayList<String>();

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

public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}

public int getUserid() {
return userid;
}

public void setUserid(int userid) {
this.userid = userid;
}

public Set<String> getOrders() {
return orders;
}
public void setOrders(Set<String> orders) {
this.orders = orders;
}
public List<String> getAddress() {
return address;
}
public void setAddress(List<String> address) {
this.address = address;
}

}

可以看到User类有一个List和一个Set,用来保存String的集合,这里有一个要注意的地方,1,集合类型只能使用通用类型,即List就是抽象的List不能是ArrayList等具体实现的List,Set也不能是HashSet等具体的Set;2,而且必须用一个具体的List或者Set来赋值,否则空指针。

2.编写bean.hbn.xml文件,在com.bean包下新建:

<?xml version="1.0" encoding='GBK'?>  
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="com.bean">
<class name="User" table="user">
<id name="userid" column="userid">
<generator class="identity"></generator>
</id>
<property name="name" column="name" type="java.lang.String"
length="16"></property>
<property name="password" column="password" type="java.lang.String"
length="16" />
<property name="gender" column="gender" type="java.lang.Integer" length="1" />

<set name="orders" table= "`order`" >
<key column="userid" not-null="true"></key>
<element type="java.lang.String" column="[order]" not-null="true"></element>
</set>

<list name="address" table="address">
<key column="userid" not-null="true"></key>
<list-index column="list_"></list-index>
<element type="java.lang.String" column="address" not-null="true"></element>
</list>
</class>
</hibernate-mapping>

<id>元素制定了表的主键,generator是主键的生成策略,identity是数字类型的,uuid是string的。重点是list元素,name是主表中的集合属性的名字,table是新表的表名,key是新表中的外键,cloumn指明了是外键是主表中的哪个属性,由于list是有序集合,因此必须在新表中添加一个索引来记录顺序,list-index元素就是干这个的,element元素则是新表中存放集合数据的列。

也就是说,一个带有集合属性的实体会产生两张表,一张是实体基本表,另外一张是集合表,集合表要有一个外键指向基本表,然后有一个自己的列存放集合数据,这两张表才能共同存储一个带有集合的实体。当然若是list,新表还要有index列存顺序,那么新表中的index和外键共同构成主键。

Set同理,只不过它无序,配置文件不需要list-index元素,那么外键和数据列共同构成主键。
3.测试类:

package com.test;

import javax.sql.rowset.serial.SerialArray;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.bean.User;

public class Main {

/**
* @param args
*/
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();

SessionFactory sessionFactory = cfg.buildSessionFactory();

Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
User user = new User();
user.setName("wetwertwerwteter");

session.save(user);
tr.commit();
session.close();
sessionFactory.close();
}

}

hibernate3必须使用事务才能存储数据,光用session不行的。

4.配置hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->
<!-- <property name="connection.pool_size">1</property> -->

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Enable Hibernate's automatic session context management -->
<!-- <property name="current_session_context_class">thread</property> -->

<!-- Disable the second-level cache -->
<!-- <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> -->

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">update</property> -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/bean/bean.hbm.xml"/>
</session-factory>
</hibernate-configuration>



最终数据库生成了3张表:

Hibernate 简单数据集合映射_外键

至此,带有基本类型的集合属性实体的存储就弄清楚了。