Hibernate 3.2 学习笔记 映射集合类

来源:互联网 发布:ports.ubuntu.com 编辑:程序博客网 时间:2024/06/05 02:47

映射值属性集合类
值属性集合类没有单独的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  在内存中排序
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());
                }
原创粉丝点击