对于hibernate中,集合属性在Hibernate的映射文件中绝对是个非常重要的内容,理解和熟练掌握常用的集合属性则显得更为重要.这里,阿堂根据自己的学习所得体合,参考有关文章的基础上,自己建表和亲自动手写了大部分代码,并且将测试结果以图示的效果放到博客上,供朋友们学习,希望能对朋友们有所帮助,阿堂更希望朋友们参与交流和讨论来共同提高!
list是有序集合,因此持久化类到数据库时必须增加一列来表示集合元素的次序。看下面的持久化类,该person类有个集合属性schools,该属性对应多个学校。集合属性只能以接口声明。例如在下面的代码中,schools的类型只能是List,不能是ArrayList,但该集合属性必须使用实现类完成初始化.
public class Person implements java.io.Serializable {
// Fields
private static final long serialVersionUID = -7919195903369450389L;
private Integer id;
private Integer age;
private String name;
//集合属性list:学校
private List schools=new ArrayList();
// Constructors
public Person() {
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public List getSchools() {
return schools;
}
public void setSchools(List schools) {
this.schools = schools;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
该持久化类的标识属性和普通属性的映射与前面相同,不同的是增加了集合属性。对本例的List集合属性,应该使用list元素完成映射。list元素要求list-index的子元素来映射有序集合的次序列。集合属性的值不可能与持久化类存储在同一个表内,集合属性会存存放在另外的表中,因此,必须以外键关联.以key元素来映射该外键列。下面是该持久化尖的映射文件.
有了pojo,也有了映射文件,该类可以完成持久化操作访问,用于完成持久化的主程序如下
public class PersonManager
{
public static void main(String[] args)
{
PersonManager mgr = new PersonManager();
mgr.createAndStorePerson();
HibernateUtil.sessionFactory.close();
}
private void createAndStorePerson()
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Person yeeku = new Person();
yeeku.setAge(29);
yeeku.setName("aaa");
List l = new ArrayList();
l.add("小学");
l.add("中学");
yeeku.setSchools(l);
session.save(yeeku); tx.commit();
HibernateUtil.closeSession();
}
}
所建数据表及运行效果图示如下
use hibernate
create table person
(
id int identity(1,1) primary key not null,
name varchar(20) not null,
age int not null,
)
create table school
(
id int identity(1,1) primary key not null,
personid int constraint fk_person_school foreign key(personid) references person(id) not null,
list_order int not null,
school_name varchar(20) not null
)
程序运行结束后,数据库将生成两个表: 一个表用于保存持久化类Person的基本属性,别一个表school将用于保存集合属性schools
二.set集合属性
------------------------------------------------------------
public class Person implements java.io.Serializable {
// Fields
private static final long serialVersionUID = -7919195903369450389L;
private Integer id;
private Integer age;
private String name;
//集合属性list:学校
private Set schools = new HashSet();
// Constructors
public Person() {
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getSchools() {
return schools;
}
public void setSchools(Set schools) {
this.schools = schools;
}
}
---------------------------------------------------------------
public class PersonManager
{
public static void main(String[] args)
{
PersonManager mgr = new PersonManager();
mgr.createAndStorePerson();
HibernateUtil.sessionFactory.close();
}
private void createAndStorePerson()
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Person yeeku = new Person();
yeeku.setAge(29);
yeeku.setName("aaa");
Set s = new HashSet();
s.add("小学");
s.add("中学");
yeeku.setSchools(s);
session.save(yeeku);
tx.commit();
HibernateUtil.closeSession();
}
}
---------------------------------------------------------------------
Set集合属性的映射与List非常相似,但因为Set是无序、不可得复的集合。因此,set元素无须使用index元素来指定集合元素的次序.与list相同的是.Set集合属性同样需要外键列,用于持久化类的集合属性的关联。
Set集合属性声明时,只能使用Set接口,不能使用实现类.
将上面示例的List集合属性改为Set集合属性即可,程序就不再重复了
映射文件夹也与List集合属性的映射相似,区别在于set元素,无须增加index列来保存元素的次序。下面是Set集合的属性的映射文件.
-------------------------------------------------------------------------
上面的映射文件中,element元素用于映射集合属性里的每个元素,该元素有个not-null属性,该属性默认为false,即该列默认为空.
对于List和Set两种集合属性,List集合的元素有顺序,而Set集合属性的元素没有顺序。当集合属性在另外的表中存储时,List集合属性可以用关联持久化类的外键和集合次序作为联合主键。但Set集合没有次序列,则以关联持久化类的外键和元素列作为联合主键,前提是元素不能为空(element不能为空,该表才有联合主键,否则该表没有主键)
use hibernate
create table person
(
id int identity(1,1) primary key not null,
name varchar(20) not null,
age int not null,
)
create table school
(
id int identity(1,1) primary key not null,
personid int constraint fk_person_school foreign key(personid) references person(id) not null,
school_name varchar(20) not null
)
三.Map集合属性
Map集合属性不仅需要映射属性value,还需要映射属性key。映射Map集合属性时,同样需要外键列,同时还必须指定Map的key列。显然,系统将以键列和key类作为联合主键。
与所有集合属性类似的是,集合属性的声明只能使用接口。
看下面的pojo类:
public class Person implements java.io.Serializable {
// Fields
private static final long serialVersionUID = -7919195903369450389L;
private Integer id;
private Integer age;
private String name;
//集合属性list:学校
private Map scores=new HashMap();
// Constructors
public Person() {
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map getScores() {
return scores;
}
public void setScores(Map scores) {
this.scores = scores;
}
}
-----------------------------------------------
配置文件
<class name="Person">
<id name="id" column="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<map name="scores" table="score">
<key column="personid" not-null="true"/>
<map-key column="xueke" type="string"/>
<element column="fenshu" type="float"/>
</map>
</class>
------------------------------------------------------------
public class PersonManager
{
public static void main(String[] args)
{
PersonManager mgr = new PersonManager();
mgr.createAndStorePerson();
HibernateUtil.sessionFactory.close();
}
private void createAndStorePerson()
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Person yeeku = new Person();
yeeku.setAge(29);
yeeku.setName("aaa");
Map m = new HashMap();
m.put("语文" , new Float(56f));
m.put("英文" , new Float(23f));
yeeku.setScores(m);
session.save(yeeku);
tx.commit();
HibernateUtil.closeSession();
}
}
-----------------------------------------
use hibernate
create table person
(
id int identity(1,1) primary key not null,
name varchar(20) not null,
age int not null,
)
create table score
(
id int identity(1,1) primary key not null,
personid int constraint fk_person_school foreign key(personid) references person(id) not null,
xueke varchar(20) not null,
fenshu float not null
)
Map集合属性应使用ma元素需要key和map-key两个子元素。其中key子元素用于映射外键列,而map-key则用于映射Map集合的key.该持久化类的映射文件如下.
程序运行结束后,保存集合属性scores的表将以personid和xueke作为联合主键.
注意:map-key和element元素都必须确定type属性.