Hibernate 3.2 学习笔记 映射集合类
2006-08-31 05:49
309 查看
映射值属性集合类
值属性集合类没有单独的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
<?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>
<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 SessionFactory sessionFactory;
static
...{
try
...{
Configuration config=new Configuration();
sessionFactory=config.configure().buildSessionFactory();
}
catch(Exception e)
...{
e.printStackTrace();
}
}
public void saveCustomer(Object customer)throws Exception
...{
Session session=sessionFactory.openSession();
Transaction tx=null;
try
...{
tx=session.beginTransaction();
session.save(customer);
tx.commit();
}
catch(Exception e)
...{
if(tx!=null)
...{
tx.rollback();
}
throw e;
}
finally
...{
session.close();
}
}
public Customer loadCustomer(Long id)throws Exception
...{
Session session=sessionFactory.openSession();
Transaction tx=null;
try
...{
tx=session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class, id);
Hibernate.initialize(customer.getImages());
tx.commit();
return customer;
}
catch(Exception e)
...{
if(tx!=null)
...{
tx.rollback();
}
throw e;
}
finally
...{
session.close();
}
}
public void test()throws Exception
...{
Set images=new HashSet();
images.add("image1.jpg");
images.add("image4.jpg");
images.add("image2.jpg");
images.add("image5.jpg");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Iterator it = customer.getImages().iterator();
while(it.hasNext())
...{
String filename=(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
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.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
<?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>
<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>
测试代码
List images=new ArrayList();
images.add("image1.jpg");
images.add("image4.jpg");
images.add("image2.jpg");
images.add("image2.jpg");
images.add("image5.jpg");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
List it = customer.getImages();
for(int i=0; i<=it.size()-1; i++)
...{
String fileName=(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
<?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>
<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
测试代码 变成
Map images=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");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Map im = customer.getImages();
Set keys=im.keySet();
Iterator it=keys.iterator();
while(it.hasNext())
...{
String keyname=(String)it.next();
String fileName=(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
<?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>
<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;
// Generated 2006-8-30 5:27:45 by Hibernate Tools 3.2.0.beta7
import java.util.*;
/** *//**
* Customer generated by hbm2java
*/
public class Customer implements java.io.Serializable ...{
// Fields
private long id;
private String name;
private int age;
private Set images=new TreeSet();
// Constructors
/** *//** default constructor */
public Customer() ...{
}
/** *//** full constructor */
public Customer(String name, int age, Set images) ...{
this.name = name;
this.age = age;
this.images = images;
}
// Property accessors
public long getId() ...{
return this.id;
}
public void setId(long id) ...{
this.id = id;
}
public String getName() ...{
return this.name;
}
public void setName(String name) ...{
this.name = name;
}
public int getAge() ...{
return this.age;
}
public void setAge(int age) ...{
this.age = age;
}
public Set getImages() ...{
return this.images;
}
public void setImages(Set images) ...{
this.images = images;
}
}
测试代码
Set images=new TreeSet();
images.add("image1.jpg");
images.add("image4.jpg");
images.add("image2.jpg");
images.add("image5.jpg");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Iterator it = customer.getImages().iterator();
while(it.hasNext())
...{
String filename=(String)it.next();
System.out.println(customer.getName()+ " " + filename);
}
可以客户化 排序方式 要实现comparator接口
注意: 可能需要手动修改POJO
images集合必须是SortedSet类型
2 map
Customer.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>
<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;
// Generated 2006-8-30 6:00:11 by Hibernate Tools 3.2.0.beta7
import java.util.*;
/** *//**
* Customer generated by hbm2java
*/
public class Customer implements java.io.Serializable ...{
// Fields
private long id;
private String name;
private int age;
private Map images=new TreeMap();
// Constructors
/** *//** default constructor */
public Customer() ...{
}
/** *//** full constructor */
public Customer(String name, int age, Map images) ...{
this.name = name;
this.age = age;
this.images = images;
}
// Property accessors
public long getId() ...{
return this.id;
}
public void setId(long id) ...{
this.id = id;
}
public String getName() ...{
return this.name;
}
public void setName(String name) ...{
this.name = name;
}
public int getAge() ...{
return this.age;
}
public void setAge(int age) ...{
this.age = age;
}
public Map getImages() ...{
return this.images;
}
public void setImages(Map images) ...{
this.images = images;
}
}
注意: 可能需要手动修改POJO
images集合必须是SortedMap类型
order-by 在数据库中排序
只需在元素里加上 order-by属性
如
<set name="images" table="IMAGES"
inverse="false"
cascade="save-update"
lazy="true"
order-by="FILENAME asc">
<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
<?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>
<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_NAME asc">
<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;
// Generated 2006-8-30 20:35:11 by Hibernate Tools 3.2.0.beta7
/** *//**
* Image generated by hbm2java
*/
public class Image implements java.io.Serializable ...{
// Fields
private String name;
private String filename;
private Integer sizeX;
private Integer sizeY;
private Customer imageCustomer;
// Constructors
/** *//** default constructor */
public Image() ...{
}
/** *//** full constructor */
public Image(String name, String filename, Integer sizeX, Integer sizeY) ...{
this.name = name;
this.filename = filename;
this.sizeX = sizeX;
this.sizeY = sizeY;
}
// Property accessors
public String getName() ...{
return this.name;
}
public void setName(String name) ...{
this.name = name;
}
public String getFilename() ...{
return this.filename;
}
public void setFilename(String filename) ...{
this.filename = filename;
}
public Integer getSizeX() ...{
return this.sizeX;
}
public void setSizeX(Integer sizeX) ...{
this.sizeX = sizeX;
}
public Integer getSizeY() ...{
return this.sizeY;
}
public void setSizeY(Integer sizeY) ...{
this.sizeY = sizeY;
}
public Customer getImageCustomer()
...{
return this.imageCustomer;
}
public void setImageCustomer(Customer imageCustomer)
...{
this.imageCustomer=imageCustomer;
}
}
测试代码
Set images=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));
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Iterator it = customer.getImages().iterator();
while(it.hasNext())
...{
Image im=(Image)it.next();
System.out.println(c.getName()+" "+im.getName()
+" "+im.getFilename()+" "+im.getSizeX()+" "+im.getSizeY());
}
值属性集合类没有单独的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
<?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>
<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 SessionFactory sessionFactory;
static
...{
try
...{
Configuration config=new Configuration();
sessionFactory=config.configure().buildSessionFactory();
}
catch(Exception e)
...{
e.printStackTrace();
}
}
public void saveCustomer(Object customer)throws Exception
...{
Session session=sessionFactory.openSession();
Transaction tx=null;
try
...{
tx=session.beginTransaction();
session.save(customer);
tx.commit();
}
catch(Exception e)
...{
if(tx!=null)
...{
tx.rollback();
}
throw e;
}
finally
...{
session.close();
}
}
public Customer loadCustomer(Long id)throws Exception
...{
Session session=sessionFactory.openSession();
Transaction tx=null;
try
...{
tx=session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class, id);
Hibernate.initialize(customer.getImages());
tx.commit();
return customer;
}
catch(Exception e)
...{
if(tx!=null)
...{
tx.rollback();
}
throw e;
}
finally
...{
session.close();
}
}
public void test()throws Exception
...{
Set images=new HashSet();
images.add("image1.jpg");
images.add("image4.jpg");
images.add("image2.jpg");
images.add("image5.jpg");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Iterator it = customer.getImages().iterator();
while(it.hasNext())
...{
String filename=(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
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.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
<?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>
<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>
测试代码
List images=new ArrayList();
images.add("image1.jpg");
images.add("image4.jpg");
images.add("image2.jpg");
images.add("image2.jpg");
images.add("image5.jpg");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
List it = customer.getImages();
for(int i=0; i<=it.size()-1; i++)
...{
String fileName=(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
<?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>
<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
测试代码 变成
Map images=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");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Map im = customer.getImages();
Set keys=im.keySet();
Iterator it=keys.iterator();
while(it.hasNext())
...{
String keyname=(String)it.next();
String fileName=(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
<?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>
<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;
// Generated 2006-8-30 5:27:45 by Hibernate Tools 3.2.0.beta7
import java.util.*;
/** *//**
* Customer generated by hbm2java
*/
public class Customer implements java.io.Serializable ...{
// Fields
private long id;
private String name;
private int age;
private Set images=new TreeSet();
// Constructors
/** *//** default constructor */
public Customer() ...{
}
/** *//** full constructor */
public Customer(String name, int age, Set images) ...{
this.name = name;
this.age = age;
this.images = images;
}
// Property accessors
public long getId() ...{
return this.id;
}
public void setId(long id) ...{
this.id = id;
}
public String getName() ...{
return this.name;
}
public void setName(String name) ...{
this.name = name;
}
public int getAge() ...{
return this.age;
}
public void setAge(int age) ...{
this.age = age;
}
public Set getImages() ...{
return this.images;
}
public void setImages(Set images) ...{
this.images = images;
}
}
测试代码
Set images=new TreeSet();
images.add("image1.jpg");
images.add("image4.jpg");
images.add("image2.jpg");
images.add("image5.jpg");
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Iterator it = customer.getImages().iterator();
while(it.hasNext())
...{
String filename=(String)it.next();
System.out.println(customer.getName()+ " " + filename);
}
可以客户化 排序方式 要实现comparator接口
注意: 可能需要手动修改POJO
images集合必须是SortedSet类型
2 map
Customer.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>
<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;
// Generated 2006-8-30 6:00:11 by Hibernate Tools 3.2.0.beta7
import java.util.*;
/** *//**
* Customer generated by hbm2java
*/
public class Customer implements java.io.Serializable ...{
// Fields
private long id;
private String name;
private int age;
private Map images=new TreeMap();
// Constructors
/** *//** default constructor */
public Customer() ...{
}
/** *//** full constructor */
public Customer(String name, int age, Map images) ...{
this.name = name;
this.age = age;
this.images = images;
}
// Property accessors
public long getId() ...{
return this.id;
}
public void setId(long id) ...{
this.id = id;
}
public String getName() ...{
return this.name;
}
public void setName(String name) ...{
this.name = name;
}
public int getAge() ...{
return this.age;
}
public void setAge(int age) ...{
this.age = age;
}
public Map getImages() ...{
return this.images;
}
public void setImages(Map images) ...{
this.images = images;
}
}
注意: 可能需要手动修改POJO
images集合必须是SortedMap类型
order-by 在数据库中排序
只需在元素里加上 order-by属性
如
<set name="images" table="IMAGES"
inverse="false"
cascade="save-update"
lazy="true"
order-by="FILENAME asc">
<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
<?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>
<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_NAME asc">
<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;
// Generated 2006-8-30 20:35:11 by Hibernate Tools 3.2.0.beta7
/** *//**
* Image generated by hbm2java
*/
public class Image implements java.io.Serializable ...{
// Fields
private String name;
private String filename;
private Integer sizeX;
private Integer sizeY;
private Customer imageCustomer;
// Constructors
/** *//** default constructor */
public Image() ...{
}
/** *//** full constructor */
public Image(String name, String filename, Integer sizeX, Integer sizeY) ...{
this.name = name;
this.filename = filename;
this.sizeX = sizeX;
this.sizeY = sizeY;
}
// Property accessors
public String getName() ...{
return this.name;
}
public void setName(String name) ...{
this.name = name;
}
public String getFilename() ...{
return this.filename;
}
public void setFilename(String filename) ...{
this.filename = filename;
}
public Integer getSizeX() ...{
return this.sizeX;
}
public void setSizeX(Integer sizeX) ...{
this.sizeX = sizeX;
}
public Integer getSizeY() ...{
return this.sizeY;
}
public void setSizeY(Integer sizeY) ...{
this.sizeY = sizeY;
}
public Customer getImageCustomer()
...{
return this.imageCustomer;
}
public void setImageCustomer(Customer imageCustomer)
...{
this.imageCustomer=imageCustomer;
}
}
测试代码
Set images=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));
Customer customer = new Customer("Tom", 21, images);
saveCustomer(customer);
Customer c=loadCustomer(new Long(1));
System.out.println(customer.getImages().getClass().getName());
Iterator it = customer.getImages().iterator();
while(it.hasNext())
...{
Image im=(Image)it.next();
System.out.println(c.getName()+" "+im.getName()
+" "+im.getFilename()+" "+im.getSizeX()+" "+im.getSizeY());
}
相关文章推荐
- Hibernate3.2 学习笔记 映射的基本元素和属性
- Hibernate 3.2 学习笔记 映射实体关联关系
- Hibernate 3.2 学习笔记 映射继承关系
- Hibernate学习笔记 多表映射
- Hibernate学习之 -- 使用Middlegen-Hibernate-r5创建oracle10g的table的hibernate映射文件,Hibernate学习笔记三 ---持久化类和关系数据
- hibernate3.3.2学习笔记---映射继承的关系
- 【Hibernate学习笔记】映射继承关系
- [学习]Hibernate 3.2 学习笔记之三
- Hibernate 学习笔记07 --集合映射_&_继承映射
- 【Hibernate学习笔记】Hibernate的内置映射类型
- Hibernate视频学习笔记(6)一对多关联映射
- Hibernate学习笔记(五)----关系映射
- Hibernate学习笔记(七)【映射值类型集合】
- SSH之hibernate学习笔记----关系映射
- Hibernate学习笔记:继承映射之每个子类一张表
- Hibernate学习笔记:继承映射之每个子类一张表,使用辨别标志
- Hibernate学习笔记-------继承关系映射
- Hibernate学习笔记--第二篇 关联关系映射 many –to –one
- Hibernate学习笔记3--映射关联关系
- Hibernate 学习笔记-1-3(Hibernate的基本映射以及几种主键生成策略的测试)