对于hibernate中,集合属性在Hibernate的映射文件中是非常常见的,也是非常重要的内容,理解和熟练掌握常用的集合属性则显得更为重要。在hibernate的配置文件中,例如每个人的考试成绩,就是典型的Map结构,每门功课对应一门成绩。或者更简单的集合属性,某个企业的部门,一个企业通常对应多个部门等。集合属性是现实生活中非常普遍的属性关系。集合属性大致有两种:第一种是单纯的集合属性,例如像List,Set或数组等集合属性;还有一种就是Map结构的集合属性。每个属性都有对应的key映射.
集合属性的元素大致有如下几种:
(1)<set>元素:可以映射类型为java.util.Set接口的属性,它的元素存放没有顺序且不允许重复,也可以映射类型为java.util.SortSet接口的属性,它的元素可以按自然属性排序
(2)<list>元素:可以映射类型为java.util.List接口的属性,它需要在结合属性对象的数据库表中用一个额外的索引列保存每一个元素的位置,即是有属性可重复的。
(3)<bag>元素:可以映射java.util.Collection接口的属性,它的元素可能重复,但不保存属性,和set差不多,正因为有它,是因为如果通常使用list比较多,并且不想让添加一列的话,就用它。
(4)<map>元素:可以映射为java.util.Map接口的属性,它的元素以键值对的形式保存,也是无序的,也可以映射类型为java.util.SortMap接口的属性,它的元素可以按自然顺序排序。
(5)<array>元素:可以映射类型为数组的属性,但在实际运用中用的极少
在这篇博客我们主要来看一下,map属性映射的详细情况
Map属性也是比较常见的属性类型,比如,一个组队内有多个学生,学生就是一个名字对应着相应的名字,下面我们就根据这个示例详细看一下:
首先看一下实体:team.java
public class Team { private Stringid; private StringteamName; private Mapstudents = new HashMap(); *************set、get方法 }
下面我们来具体看一下具体的实体映射配置
Team.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> <classname="com.shengsiyuan.hibernate.Team" table="team"> <idname="id" column="id" type="string"> <generatorclass="uuid"></generator> </id> <propertyname="teamName" column="teamName"type="string"></property> <mapname="students" table="student"> <keycolumn="team_id"></key> <indexcolumn="name" type="java.lang.String"></index><!--指定的是Map中的key值 --> <element column="description" type="java.lang.String"></element><!--指定的是Map中的value值 --> </map> </class> </hibernate-mapping>
从上边配置文件可以看出,其实map属性映射的配置文件其他的配置都和我们以前配置一样,只是在配置map属性的时候有点不一样而已,下面我们就具体看一下map属性配置:首先要给大家说明的是,虽然我们只有一个配置文件,但是上面的配置会生成两个数据库表的,map属性里的会单独生成一个数据库表,这个表包含map的key和value,还有一个外键。map属性配置内的key标签指定的是map对应表中数据所参考的team的id,也就是说这个外键对应team的主键。Map标签内的index标签对应指的是map数据中的key值,element标签指定的是map数据中的value值。
其实上面我们看到的map中value值只是简单数据类型,但是在实际开发中,这里的value大多数都是对象的形式的。现在我们还是以上面的例子来看一下,这里的value是对象的时候我们该如何配置:当value是对象的时候,我们就不能再简单的用一个配置文件来生成两个数据库表了,这时我们需要建立我们的team类。还需要建立value对应的student实体类
首先我们来看一下实体:Team.java
public class Team { private String id; private StringteamName; private Mapstudents = new HashMap(); *********省略set、get方法}Student.java
public class Student { private String id; private StringcardId; private Stringname; private int age; private Team team; ********省略set、get方法 }下面我们继续来看一下相关的实体映射文件
Team.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> <classname="com.shengsiyuan.hibernate.Team" table="team"> <idname="id" column="id" type="string"> <generatorclass="uuid"></generator> </id> <propertyname="teamName" column="teamName"type="string"></property> <mapname="students" table="student" cascade="all"> <keycolumn="team_id"></key> <index column="card_id"type="java.lang.String"></index> <!--指定的是Map中的key值 --> <one-to-manyclass="com.shengsiyuan.hibernate.Student"/> </map> </class> </hibernate-mapping>
通过上面的配置文件我们可以看出,这个配置文件几乎和简单数据类型的配置文件差不多,仅仅不同的是map标签内的element标签换成了one-to-many标签,这样充分可以说明:
map标签中的element子标签映射的是原子类型(string,date,int,long…),即能够直接映射到数据库表字段上的类型,而one-to-many映射的则是实体类型,指的是无法映射到表的某个字段,而是要映射到整张表的类型。但有一点需要注意的是,在map标签中的one-to-many中不要设置inverse=true,因为如果要让map值中的对象去维护两者之间的关系的话,在保存数据中很有可能外键添加不上,被设置为null
下面在来看一下student.hbm.xml
<?xmlversion="1.0"?> <!DOCTYPEhibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <classname="com.shengsiyuan.hibernate.Student"table="student"> <id name="id" column="id"type="string"> <generatorclass="uuid"></generator> </id> <property name="cardId"column="card_id" type="string"></property> <property name="name"column="name" type="string"></property> <property name="age"column="age" type="int"></property> <many-to-one name="team"column="team_id" class="com.shengsiyuan.hibernate.Team"cascade="none" fetch="join"> </many-to-one> </class> </hibernate-mapping>细心的同学可以发现,这个配置文件和一对多关系映射中的多的一方配置的差不多,其实就是一样的,所以在这里就不在赘述了。