映射值属性集合类
值属性集合类没有单独的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) 来初始化集合
<
set
name
="images"
table
="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true"
>
<
key
column
="CUSTOMER_ID"
/>
<
element
column
="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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
set
name
="images"
table
="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true"
>
<
key
column
="CUSTOMER_ID"
/>
<
element
column
="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
package
ergal;
import
java.util.
*
;
import
org.hibernate.
*
;
import
org.hibernate.cfg.
*
;
import
java.sql.
*
;
public
class
BusinessService
...
{
public
static
SessionFactorysessionFactory;
static
...
{
try
...
{
Configurationconfig
=
new
Configuration();
sessionFactory
=
config.configure().buildSessionFactory();
}
catch
(Exceptione)
...
{
e.printStackTrace();
}
}
public
void
saveCustomer(Objectcustomer)
throws
Exception
...
{
Sessionsession
=
sessionFactory.openSession();
Transactiontx
=
null
;
try
...
{
tx
=
session.beginTransaction();
session.save(customer);
tx.commit();
}
catch
(Exceptione)
...
{
if
(tx
!=
null
)
...
{
tx.rollback();
}
throw
e;
}
finally
...
{
session.close();
}
}
public
CustomerloadCustomer(Longid)
throws
Exception
...
{
Sessionsession
=
sessionFactory.openSession();
Transactiontx
=
null
;
try
...
{
tx
=
session.beginTransaction();
Customercustomer
=
(Customer)session.load(Customer.
class
,id);
Hibernate.initialize(customer.getImages());
tx.commit();
return
customer;
}
catch
(Exceptione)
...
{
if
(tx
!=
null
)
...
{
tx.rollback();
}
throw
e;
}
finally
...
{
session.close();
}
}
public
void
test()
throws
Exception
...
{
Setimages
=
new
HashSet();
images.add(
"
image1.jpg
"
);
images.add(
"
image4.jpg
"
);
images.add(
"
image2.jpg
"
);
images.add(
"
image5.jpg
"
);
Customercustomer
=
new
Customer(
"
Tom
"
,
21
,images);
saveCustomer(customer);
Customerc
=
loadCustomer(
new
Long(
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);
}
}
public
static
void
main(String[]args)
throws
Exception
...
{
new
BusinessService().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) 来初始化集合
<
idbag
name
="images"
table
="IMAGES"
lazy
="true"
>
<
collection-id
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
collection-id
>
<
key
column
="CUSTOMER_ID"
/>
<
element
column
="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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
idbag
name
="images"
table
="IMAGES"
lazy
="true"
>
<
collection-id
type
="long"
column
="ID"
>
<
generator
class
="increment"
/>
</
collection-id
>
<
key
column
="CUSTOMER_ID"
/>
<
element
column
="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) 来初始化集合
<
list
name
="images"
table
="IMAGES"
lazy
="true"
>
<
key
column
="CUSTOMER_ID"
/>
<
index
column
="POSTION"
/>
<
element
column
="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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
list
name
="images"
table
="IMAGES"
lazy
="true"
>
<
key
column
="CUSTOMER_ID"
/>
<
index
column
="POSTION"
/>
<
element
column
="FILENAME"
type
="string"
not-null
="true"
/>
</
list
>
</
class
>
</
hibernate-mapping
>
测试代码
Listimages
=
new
ArrayList();
images.add(
"
image1.jpg
"
);
images.add(
"
image4.jpg
"
);
images.add(
"
image2.jpg
"
);
images.add(
"
image2.jpg
"
);
images.add(
"
image5.jpg
"
);
Customercustomer
=
new
Customer(
"
Tom
"
,
21
,images);
saveCustomer(customer);
Customerc
=
loadCustomer(
new
Long(
1
));
System.out.println(customer.getImages().getClass().getName());
Listit
=
customer.getImages();
for
(
int
i
=
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) 来初始化集合
<
map
name
="images"
table
="IMAGES"
lazy
="true"
>
<
key
column
="CUSTOMER_ID"
/>
<
index
column
="IMAGE_NAME"
type
="string"
/>
<
element
column
="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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
map
name
="images"
table
="IMAGES"
lazy
="true"
>
<
key
column
="CUSTOMER_ID"
/>
<
index
column
="IMAGE_NAME"
type
="string"
/>
<
element
column
="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
=
new
HashMap();
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
=
new
Customer(
"
Tom
"
,
21
,images);
saveCustomer(customer);
Customerc
=
loadCustomer(
new
Long(
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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
set
name
="images"
table
="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true"
sort
="natural"
>
<
key
column
="CUSTOMER_ID"
/>
<
element
column
="FILENAME"
type
="string"
not-null
="true"
/>
</
set
>
</
class
>
</
hibernate-mapping
>
Customer.java
package
ergal;
//
Generated2006-8-305:27:45byHibernateTools3.2.0.beta7
import
java.util.
*
;
/***/
/**
*Customergeneratedbyhbm2java
*/
public
class
Customer
implements
java.io.Serializable
...
{
//
Fields
private
long
id;
private
Stringname;
private
int
age;
private
Setimages
=
new
TreeSet();
//
Constructors
/***/
/**
defaultconstructor
*/
public
Customer()
...
{
}
/***/
/**
fullconstructor
*/
public
Customer(Stringname,
int
age,Setimages)
...
{
this
.name
=
name;
this
.age
=
age;
this
.images
=
images;
}
//
Propertyaccessors
public
long
getId()
...
{
return
this
.id;
}
public
void
setId(
long
id)
...
{
this
.id
=
id;
}
public
StringgetName()
...
{
return
this
.name;
}
public
void
setName(Stringname)
...
{
this
.name
=
name;
}
public
int
getAge()
...
{
return
this
.age;
}
public
void
setAge(
int
age)
...
{
this
.age
=
age;
}
public
SetgetImages()
...
{
return
this
.images;
}
public
void
setImages(Setimages)
...
{
this
.images
=
images;
}
}
测试代码
Setimages
=
new
TreeSet();
images.add(
"
image1.jpg
"
);
images.add(
"
image4.jpg
"
);
images.add(
"
image2.jpg
"
);
images.add(
"
image5.jpg
"
);
Customercustomer
=
new
Customer(
"
Tom
"
,
21
,images);
saveCustomer(customer);
Customerc
=
loadCustomer(
new
Long(
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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
map
name
="images"
table
="IMAGES"
lazy
="true"
sort
="natural"
>
<
key
column
="CUSTOMER_ID"
/>
<
index
column
="IMAGE_NAME"
type
="string"
/>
<
element
column
="FILENAME"
type
="string"
not-null
="true"
/>
</
map
>
</
class
>
</
hibernate-mapping
>
Customer.java
package
ergal;
//
Generated2006-8-306:00:11byHibernateTools3.2.0.beta7
import
java.util.
*
;
/***/
/**
*Customergeneratedbyhbm2java
*/
public
class
Customer
implements
java.io.Serializable
...
{
//
Fields
private
long
id;
private
Stringname;
private
int
age;
private
Mapimages
=
new
TreeMap();
//
Constructors
/***/
/**
defaultconstructor
*/
public
Customer()
...
{
}
/***/
/**
fullconstructor
*/
public
Customer(Stringname,
int
age,Mapimages)
...
{
this
.name
=
name;
this
.age
=
age;
this
.images
=
images;
}
//
Propertyaccessors
public
long
getId()
...
{
return
this
.id;
}
public
void
setId(
long
id)
...
{
this
.id
=
id;
}
public
StringgetName()
...
{
return
this
.name;
}
public
void
setName(Stringname)
...
{
this
.name
=
name;
}
public
int
getAge()
...
{
return
this
.age;
}
public
void
setAge(
int
age)
...
{
this
.age
=
age;
}
public
MapgetImages()
...
{
return
this
.images;
}
public
void
setImages(Mapimages)
...
{
this
.images
=
images;
}
}
注意: 可能需要手动修改POJO
images集合必须是SortedMap类型
order-by 在数据库中排序
只需在元素里加上 order-by属性
如
<
set
name
="images"
table
="IMAGES"
inverse
="false"
cascade
="save-update"
lazy
="true"
order-by
="FILENAMEasc"
>
<
key
column
="CUSTOMER_ID"
/>
<
element
column
="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
>
<
class
name
="ergal.Customer"
table
="CUSTOMERS"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
column
="NAME"
type
="string"
/>
<
property
name
="age"
column
="AGE"
type
="int"
/>
<
set
name
="images"
table
="IMAGES"
lazy
="true"
order-by
="IMAGE_NAMEasc"
>
<
key
column
="CUSTOMER_ID"
/>
<
composite-element
class
="ergal.Image"
>
<
parent
name
="imageCustomer"
/>
<
property
name
="name"
column
="IMAGE_NAME"
type
="string"
not-null
="true"
/>
<
property
name
="filename"
column
="FILENAME"
type
="string"
not-null
="true"
/>
<
property
name
="sizeX"
column
="SIZEX"
type
="integer"
not-null
="true"
/>
<
property
name
="sizeY"
column
="SIZEY"
type
="integer"
not-null
="true"
/>
</
composite-element
>
</
set
>
</
class
>
</
hibernate-mapping
>
Image.java
需要手动添加 Customer 字段
parent不能用hbm2java来自动产生 不知道这是不是个Bug
package
ergal;
//
Generated2006-8-3020:35:11byHibernateTools3.2.0.beta7
/***/
/**
*Imagegeneratedbyhbm2java
*/
public
class
Image
implements
java.io.Serializable
...
{
//
Fields
private
Stringname;
private
Stringfilename;
private
IntegersizeX;
private
IntegersizeY;
private
CustomerimageCustomer;
//
Constructors
/***/
/**
defaultconstructor
*/
public
Image()
...
{
}
/***/
/**
fullconstructor
*/
public
Image(Stringname,Stringfilename,IntegersizeX,IntegersizeY)
...
{
this
.name
=
name;
this
.filename
=
filename;
this
.sizeX
=
sizeX;
this
.sizeY
=
sizeY;
}
//
Propertyaccessors
public
StringgetName()
...
{
return
this
.name;
}
public
void
setName(Stringname)
...
{
this
.name
=
name;
}
public
StringgetFilename()
...
{
return
this
.filename;
}
public
void
setFilename(Stringfilename)
...
{
this
.filename
=
filename;
}
public
IntegergetSizeX()
...
{
return
this
.sizeX;
}
public
void
setSizeX(IntegersizeX)
...
{
this
.sizeX
=
sizeX;
}
public
IntegergetSizeY()
...
{
return
this
.sizeY;
}
public
void
setSizeY(IntegersizeY)
...
{
this
.sizeY
=
sizeY;
}
public
CustomergetImageCustomer()
...
{
return
this
.imageCustomer;
}
public
void
setImageCustomer(CustomerimageCustomer)
...
{
this
.imageCustomer
=
imageCustomer;
}
}
测试代码
Setimages
=
new
HashSet();
images.add(
new
Image(
"
image1
"
,
"
image1.jpg
"
,
50
,
50
));
images.add(
new
Image(
"
image4
"
,
"
image4.jpg
"
,
50
,
50
));
images.add(
new
Image(
"
image2
"
,
"
image2.jpg
"
,
50
,
50
));
images.add(
new
Image(
"
image5
"
,
"
image5.jpg
"
,
50
,
50
));
Customercustomer
=
new
Customer(
"
Tom
"
,
21
,images);
saveCustomer(customer);
Customerc
=
loadCustomer(
new
Long(
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());
}
Hibernate 3.2 学习笔记 映射集合类