您的位置:首页 > 其它

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());


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: