集合映射
在持久化类中,有时会使用到值类型的对象属性。所谓值类型的对象属性,是指它对应的类没有对象标识符属性,只能作为一个持久化类的属性使用。如果持久化类中有一个值类型的集合,那么就需要一张额外的数据库表来保存这个值类型集合的数据,这张表被称为集合表。
1、 选择集合接口
Hibernate支持大部分重要的JDK集合接口映射,主要有以下几种。
(1)、<set>元素:可以映射类型为java.util.Set接口的属性,它的元素存放没有顺序且不允许重复;也可以映射类型为java.util.SortSet接口的属性,它的元素可以按自然顺序排序。
(2)、<list>元素:可以映射类型为java.util.List接口的属性,它需要在集合属性对应的数据库表中用一个额外的索引列保存每个元素的位置。
(3)<bag>和<idbag>元素:可以映射类型为java.util.Collection 接口的属性。它的元素可能重复但不保存顺序。
(4)<map>元素:可以映射类型为java.util.Map接口的属性,它的元素形式以键/值对的形式保存,也是无序的;也可以映射类型为java.util.SortMap接口的属性,它的元素可以按自然顺序排序。
(5)、<primitive-array>或<array>元素;可以映射类型为数组的属性。但它在实际运用中用得极少。
2、映射set
public class Student {
private int id;
private String name;
private Set<String> hobbies;//爱好
public Student(){}//无惨的构造方法
//getters和setters方法
}
它对应的对象关系映射文件Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="cn.csdn.domain">
<class name="Student" table="student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="hobbies"table="student_hobby">
<key column="student_id"/>
<element type="string"column="hobbies_name"/>
</set>
</class>
</hibernate-mapping>
这样映射之后,每个学生实例的爱好都会保存在名为student_hobby的数据库表中。
3、 映射List
如果想记录学生所选择的爱好的顺序,可以把student类中的hobbies属性类型改成List类型。
public class Student {
private int id;
private String name;
private List<String> hobbies;//爱好
public Student(){}//无惨的构造方法
//getters和setters方法
}
使用<list>元素映射时,需要把一个索引列增加到集合表中,用索引列来指定元素在集合中的位置。
<listname="hobbies" table="student_hobby">
<key column="studenr_id"/>
<list-index column="order_index"/>
<element type="string"column="hobbies_name"/>
</list>
4、 映射bag
允许重复元素的无序集合被称为包(bag),但在java集合框架中并没有一个对应语义的实现类。可以使用java.util.Collection接口或java.util.List接口来表示这种语义,具体的实现由Hibernate框架内部去处理(它有persistentBag类来表示包的实现类)
public class Student {
private int id;
private String name;
private Collection<String> hobbies;//爱好
public Student(){}//无惨的构造方法
//getters和setters方法
}
对应的映射文件
<bagname="hobbies" table="student_hobbies">
<key column="student_id"/>
<element type="string"column="hobbies_name"/>
</bag>
5、 映射map
使用键/值对的方式
public class Student {
private int id;
private String name;
private Map<Long,String> hobbies;//爱好
public Student(){}//无惨的构造方法
//getters和setters方法
}
对应的映射文件
<map name="hobbies"table="student_hobbies">
<key column="student_id"/><!-- 外键咧 -->
<map-key type="long"column="hobby_id"/><!-- map中的key -->
<element type="string"column="hobbies_name"/><!--map中的值 -->
</map>
6、 排序集合和有序集合
在实际应用中,经常需要集合中的元素是按一定要求排列好顺序后在返回给使用者的,这种需求在hibernate中可能使用排序集合和有序集合来完成。
排序集合是指数据从数据库中获取到集合中时,使用一个java比较器在内存中排序存放。
public class Student {
private int id;
private String name;
private SortedSet<String> hobbies;//爱好
public Student(){}//无惨的构造方法
//getters和setters方法
}
对应的映射文件
<setname="hobbies" table="student_hobby" sort=”natural”>
<key column="student_id"/>
<element type="string"column="hobbies_name"/>
</set>
<!-
Set元素用来映射java.util.Set类型的属性
Name属性:指定要映射的属性名
Table属性:指定对应的数据库表明
Sort属性:指定排序的规则。可选值:unsorted(不排序)、natural(按compareTo()方法进行比较后排序、自定义的排序器名)
-à
有序集合是指在从数据库获取数据时就使用SQL语句的order by语句排序好,然后再封装到集合中存放。这种情况下持久化类中的集合属性仍旧使用Set或Map。但对应的映射文件中的<set>或<map>元素需要添加order-by属性来指定SQL中order by字句。映射文件如下
<setname="hobbies" table="student_hobby" order-by=”hobby_namedesc”>
<key column="student_id"/>
<element type="string"column="hobbies_name" not-null=”true”/>
</set>