`

Hibernate 3.2 学习笔记 映射集合类

 
阅读更多

映射值属性集合类
值属性集合类没有单独的OID和生命周期 实体类集合有单独的OID和生命周期
set 不允许重复
属性:

name 指定集合的属性名

table 对应的 表

lazy 延迟检索策略

inverese 有较好的update性能 但是不会按照one方来同步更新数据库(要注意)
order-by 数据库排序方式
sort 内存排序方式

元素:

<key> 定义外键

<one-to-many> 定义many 方的类

<element column="***" type="string" not-null="true"/>

注: 由于采用了延时检索策略 所以在读取的时候
用hibernate.isInitialized(Object)检查
用hibernate.initialize(java.lang.Object proxy) 来初始化集合

<setname="images"table="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true">
<keycolumn="CUSTOMER_ID"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</set>

例子
Customer.hbm.xm

<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<setname="images"table="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true">
<keycolumn="CUSTOMER_ID"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</set>

</class>

</hibernate-mapping>

运行hbm2ddl
两表
Customer
1 - ID
2 - NAME
3 - AGE
IMAGES
1 - CUSTOMER_ID
2 - FILENAME

测试代码
BusinessService.java

packageergal;

importjava.util.*;
importorg.hibernate.*;
importorg.hibernate.cfg.*;
importjava.sql.*;

publicclassBusinessService
...{
publicstaticSessionFactorysessionFactory;
static
...{
try
...{
Configurationconfig
=newConfiguration();
sessionFactory
=config.configure().buildSessionFactory();
}

catch(Exceptione)
...{
e.printStackTrace();
}

}


publicvoidsaveCustomer(Objectcustomer)throwsException
...{
Sessionsession
=sessionFactory.openSession();
Transactiontx
=null;
try
...{
tx
=session.beginTransaction();
session.save(customer);
tx.commit();
}

catch(Exceptione)
...{
if(tx!=null)
...{
tx.rollback();
}

throwe;
}

finally
...{
session.close();
}

}


publicCustomerloadCustomer(Longid)throwsException
...{
Sessionsession
=sessionFactory.openSession();
Transactiontx
=null;
try
...{
tx
=session.beginTransaction();

Customercustomer
=(Customer)session.load(Customer.class,id);
Hibernate.initialize(customer.getImages());


tx.commit();
returncustomer;
}

catch(Exceptione)
...{
if(tx!=null)
...{
tx.rollback();
}

throwe;
}

finally
...{
session.close();
}

}


publicvoidtest()throwsException
...{
Setimages
=newHashSet();
images.add(
"image1.jpg");
images.add(
"image4.jpg");
images.add(
"image2.jpg");
images.add(
"image5.jpg");

Customercustomer
=newCustomer("Tom",21,images);
saveCustomer(customer);

Customerc
=loadCustomer(newLong(1));
System.out.println(customer.getImages().getClass().getName());

Iteratorit
=customer.getImages().iterator();

while(it.hasNext())
...{
Stringfilename
=(String)it.next();
System.out.println(customer.getName()
+""+filename);
}


}


publicstaticvoidmain(String[]args)throwsException
...{
newBusinessService().test();
sessionFactory.close();
}

}

Bag 允许重复 不能排序

属性:

name 指定集合的属性名

table 对应的 表

lazy 延迟检索策略

//inverese 有较好的update性能 但是不会按照one方来同步更新数据库(要注意)
order-by 数据库排序方式

元素:
<collection-id name="" table="" lazy="">
<generator class="native"/>
<collection-id/>

<key> 定义外键

//<one-to-many> 定义many 方的类

<element column="***" type="string" not-null="true"/>

注: 由于采用了延时检索策略 所以在读取的时候
用hibernate.isInitialized(Object)检查
用hibernate.initialize(java.lang.Object proxy) 来初始化集合

<idbagname="images"table="IMAGES"lazy="true">
<collection-idtype="long"column="ID">
<generatorclass="native"/>
</collection-id>
<keycolumn="CUSTOMER_ID"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>

</idbag>

例子
Customer.hbm.xml

<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<idbagname="images"table="IMAGES"lazy="true">
<collection-idtype="long"column="ID">
<generatorclass="increment"/>
</collection-id>
<keycolumn="CUSTOMER_ID"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</idbag>

</class>

</hibernate-mapping>

注:这里的collection-id 为increment 才能正常运行
运行hbm2ddl后产生两表
customers
1 - ID
2 - NAME
3 - AGE

IMAGES
1 - CUSTOMER_ID
2 - FILENAME
3 - ID

测试代码中
原来的
Set images=new HashSet();
改成
List images=new ArrayList();

也可以用java.util.Collection来代替List

注意:

虽然可以用List但是只要是idbag 集合中的元素就不会按照索引来排序
要排序用List映射

映射List 允许存放重复元素 可以按照索引排序

属性:

name 指定集合的属性名

table 对应的 表

lazy 延迟检索策略

inverese 有较好的update性能 但是不会按照one方来同步更新数据库(要注意)

元素:

<key column=""> 定义外键
<index column=""> 设置代表索引的字段
//<one-to-many> 定义many 方的类

<element column="***" type="string" not-null="true"/>

注: 由于采用了延时检索策略 所以在读取的时候
用hibernate.isInitialized(Object)检查
用hibernate.initialize(java.lang.Object proxy) 来初始化集合

<listname="images"table="IMAGES"lazy="true">
<keycolumn="CUSTOMER_ID"/>
<indexcolumn="POSTION"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</list>

例子
Customer.hbm.xml

<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<listname="images"table="IMAGES"lazy="true">
<keycolumn="CUSTOMER_ID"/>
<indexcolumn="POSTION"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</list>

</class>

</hibernate-mapping>

测试代码

Listimages=newArrayList();
images.add(
"image1.jpg");
images.add(
"image4.jpg");
images.add(
"image2.jpg");
images.add(
"image2.jpg");
images.add(
"image5.jpg");

Customercustomer
=newCustomer("Tom",21,images);
saveCustomer(customer);

Customerc
=loadCustomer(newLong(1));
System.out.println(customer.getImages().getClass().getName());

Listit
=customer.getImages();

for(inti=0;i<=it.size()-1;i++)
...{
StringfileName
=(String)it.get(i);
System.out.println(customer.getName()
+""+fileName);
}

注意: 取得元素的方法是String fileName=(String)it.get(i);

显然这种方法是可以为索引排序的

map 每个元素包含一对键对象和值对象 不会对键对象排序

属性:

name 指定集合的属性名

table 对应的 表

lazy 延迟检索策略

//inverese 有较好的update性能 但是不会按照one方来同步更新数据库(要注意)
order-by 数据库排序方式
sort 内存排序方式
元素:

<key column=""> 定义外键
<index column="" type=""> 设置代表和键对象对应的字段
//<one-to-many> 定义many 方的类

<element column="***" type="string" not-null="true"/>

注: 由于采用了延时检索策略 所以在读取的时候
用hibernate.isInitialized(Object)检查
用hibernate.initialize(java.lang.Object proxy) 来初始化集合

<mapname="images"table="IMAGES"lazy="true">
<keycolumn="CUSTOMER_ID"/>
<indexcolumn="IMAGE_NAME"type="string"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</map>

例子
Customer.hbm.xml

<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<mapname="images"table="IMAGES"lazy="true">
<keycolumn="CUSTOMER_ID"/>
<indexcolumn="IMAGE_NAME"type="string"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</map>

</class>

</hibernate-mapping>

运行hbm2ddl后产生两表
customers
1 - ID
2 - NAME
3 - AGE

IMAGES
1 - CUSTOMER_ID
2 - FILENAME
3 - IMAGE_NAME

测试代码 变成

Mapimages=newHashMap();
images.put(
"image1","image1.jpg");
images.put(
"image4","image4.jpg");
images.put(
"image2","image2.jpg");
images.put(
"imageTwo","image2.jpg");
images.put(
"image5","image5.jpg");

Customercustomer
=newCustomer("Tom",21,images);
saveCustomer(customer);

Customerc
=loadCustomer(newLong(1));
System.out.println(customer.getImages().getClass().getName());

Mapim
=customer.getImages();
Setkeys
=im.keySet();
Iteratorit
=keys.iterator();
while(it.hasNext())
...{
Stringkeyname
=(String)it.next();
StringfileName
=(String)im.get(keyname);
System.out.println(customer.getName()
+""+keyname+""+fileName);
}

用了Map里的get(Object key) 和 keySet()方法
此方法不会对键对象排序

对集合排序

有两种方式:
在数据库中排序 order-by
在内存中排序 sort 体现在代码中 原来的Set 变成了SortedSet 查询时可以用TreeSet

<set>和<map>两种都支持
<idbag>支持 在内存中排序 sort
<list>两种都不支持
sort 在内存中排序
1 set
例子
Customer.hbm.xml

<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<setname="images"table="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true"
sort
="natural">
<keycolumn="CUSTOMER_ID"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</set>

</class>

</hibernate-mapping>

Customer.java

packageergal;
//Generated2006-8-305:27:45byHibernateTools3.2.0.beta7


importjava.util.*;

/***//**
*Customergeneratedbyhbm2java
*/

publicclassCustomerimplementsjava.io.Serializable...{

//Fields

privatelongid;
privateStringname;
privateintage;
privateSetimages=newTreeSet();

//Constructors

/***//**defaultconstructor*/
publicCustomer()...{
}


/***//**fullconstructor*/
publicCustomer(Stringname,intage,Setimages)...{
this.name=name;
this.age=age;
this.images=images;
}


//Propertyaccessors
publiclonggetId()...{
returnthis.id;
}


publicvoidsetId(longid)...{
this.id=id;
}

publicStringgetName()...{
returnthis.name;
}


publicvoidsetName(Stringname)...{
this.name=name;
}

publicintgetAge()...{
returnthis.age;
}


publicvoidsetAge(intage)...{
this.age=age;
}

publicSetgetImages()...{
returnthis.images;
}


publicvoidsetImages(Setimages)...{
this.images=images;
}



}

测试代码

Setimages=newTreeSet();
images.add(
"image1.jpg");
images.add(
"image4.jpg");
images.add(
"image2.jpg");
images.add(
"image5.jpg");

Customercustomer
=newCustomer("Tom",21,images);
saveCustomer(customer);

Customerc
=loadCustomer(newLong(1));
System.out.println(customer.getImages().getClass().getName());

Iteratorit
=customer.getImages().iterator();

while(it.hasNext())
...{
Stringfilename
=(String)it.next();
System.out.println(customer.getName()
+""+filename);
}

可以客户化 排序方式 要实现comparator接口

注意: 可能需要手动修改POJO
images集合必须是SortedSet类型

2 map

Customer.hbm.xml

<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<mapname="images"table="IMAGES"lazy="true"sort="natural">
<keycolumn="CUSTOMER_ID"/>
<indexcolumn="IMAGE_NAME"type="string"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</map>

</class>

</hibernate-mapping>

Customer.java

packageergal;
//Generated2006-8-306:00:11byHibernateTools3.2.0.beta7


importjava.util.*;

/***//**
*Customergeneratedbyhbm2java
*/

publicclassCustomerimplementsjava.io.Serializable...{

//Fields

privatelongid;
privateStringname;
privateintage;
privateMapimages=newTreeMap();

//Constructors

/***//**defaultconstructor*/
publicCustomer()...{
}


/***//**fullconstructor*/
publicCustomer(Stringname,intage,Mapimages)...{
this.name=name;
this.age=age;
this.images=images;
}


//Propertyaccessors
publiclonggetId()...{
returnthis.id;
}


publicvoidsetId(longid)...{
this.id=id;
}

publicStringgetName()...{
returnthis.name;
}


publicvoidsetName(Stringname)...{
this.name=name;
}

publicintgetAge()...{
returnthis.age;
}


publicvoidsetAge(intage)...{
this.age=age;
}

publicMapgetImages()...{
returnthis.images;
}


publicvoidsetImages(Mapimages)...{
this.images=images;
}


}

注意: 可能需要手动修改POJO
images集合必须是SortedMap类型

order-by 在数据库中排序

只需在元素里加上 order-by属性

<setname="images"table="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true"
order-by
="FILENAMEasc">
<keycolumn="CUSTOMER_ID"/>
<elementcolumn="FILENAME"type="string"not-null="true"/>
</set>

也可以加上sql函数
如 order-by="lower(FILENAME) asc"

映射组件集合

组件也是一种值对象

它必须实现java.io.Serializable接口

它必须重新实现equals()和hashCode()方法, 始终和组合关键字在数据库中的概念保持一致

例子
Customer.hbm.xml

<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

<classname="ergal.Customer"table="CUSTOMERS"lazy="true">
<idname="id"type="long"column="ID">
<generatorclass="native"/>
</id>

<propertyname="name"column="NAME"type="string"/>

<propertyname="age"column="AGE"type="int"/>


<setname="images"table="IMAGES"lazy="true"order-by="IMAGE_NAMEasc">
<keycolumn="CUSTOMER_ID"/>
<composite-elementclass="ergal.Image">
<parentname="imageCustomer"/>
<propertyname="name"column="IMAGE_NAME"type="string"not-null="true"/>
<propertyname="filename"column="FILENAME"type="string"not-null="true"/>
<propertyname="sizeX"column="SIZEX"type="integer"not-null="true"/>
<propertyname="sizeY"column="SIZEY"type="integer"not-null="true"/>
</composite-element>
</set>

</class>

</hibernate-mapping>

Image.java
需要手动添加 Customer 字段
parent不能用hbm2java来自动产生 不知道这是不是个Bug

packageergal;
//Generated2006-8-3020:35:11byHibernateTools3.2.0.beta7



/***//**
*Imagegeneratedbyhbm2java
*/

publicclassImageimplementsjava.io.Serializable...{

//Fields

privateStringname;
privateStringfilename;
privateIntegersizeX;
privateIntegersizeY;
privateCustomerimageCustomer;
//Constructors

/***//**defaultconstructor*/
publicImage()...{
}


/***//**fullconstructor*/
publicImage(Stringname,Stringfilename,IntegersizeX,IntegersizeY)...{
this.name=name;
this.filename=filename;
this.sizeX=sizeX;
this.sizeY=sizeY;
}


//Propertyaccessors
publicStringgetName()...{
returnthis.name;
}


publicvoidsetName(Stringname)...{
this.name=name;
}

publicStringgetFilename()...{
returnthis.filename;
}


publicvoidsetFilename(Stringfilename)...{
this.filename=filename;
}

publicIntegergetSizeX()...{
returnthis.sizeX;
}


publicvoidsetSizeX(IntegersizeX)...{
this.sizeX=sizeX;
}

publicIntegergetSizeY()...{
returnthis.sizeY;
}


publicvoidsetSizeY(IntegersizeY)...{
this.sizeY=sizeY;
}


publicCustomergetImageCustomer()
...{
returnthis.imageCustomer;
}


publicvoidsetImageCustomer(CustomerimageCustomer)
...{
this.imageCustomer=imageCustomer;
}


}

测试代码

Setimages=newHashSet();
images.add(
newImage("image1","image1.jpg",50,50));
images.add(
newImage("image4","image4.jpg",50,50));
images.add(
newImage("image2","image2.jpg",50,50));
images.add(
newImage("image5","image5.jpg",50,50));

Customercustomer
=newCustomer("Tom",21,images);
saveCustomer(customer);

Customerc
=loadCustomer(newLong(1));
System.out.println(customer.getImages().getClass().getName());

Iteratorit
=customer.getImages().iterator();


while(it.hasNext())
...{
Imageim
=(Image)it.next();
System.out.println(c.getName()
+""+im.getName()
+""+im.getFilename()+""+im.getSizeX()+""+im.getSizeY());
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics