ORM(Object/Relational Mapper)---Hibernate对象映射

字体大小: 中小 标准 ->行高大小: 标准

一. ORM(Object/Relational Mapper)

1. OR映射---Hibernate基本数据类型

Hibernate基本类型

Java类型

标准SQL字段类型

boolean

boolean, java.lang.Boolean

BIT

yes_no

boolean, java.lang.Boolean

CHAR(1) ( 'Y'/'N')

true_false

boolean, java.lang.Boolean

CHAR(1) ( 'Y'/'N')

byte

byte, java.lang.Byte

TINYINT

short

short, java.lang.Short

SMALLINT

integer

int, java.lang.Integer

INTEGER

long

long, java.lang.Long

BIGINT

float

float, java.lang.Float

FLOAT

double

double, java.lang.Double

DOUBLE

big_decimal

java.math.BigDecimal

NUMBERIC

character

java.lang.String

CHAR(1)

string

java.lang.String

VARCHAR

date

java.util.Date, java.sql.Date

DATE

time

java.util.Date, java.sql.Time

TIME

timestamp

java.util.Date, java.sql.TimeStamp

TIMESTAMP

calendar

java.util.Calendar

TIMESTAMP

calendar_date

java.util.Calendar

Date

clob

java.sql.Clob

CLOB

blob

java.sql.Blob

BLOB

binary

byte[]

VARBINARY, BLOB

text

java.lang.String

CLOB

seralizable

java.io.Serializable

VARBINARY, BLOB

class

java.lang.Class

VARCHAR

local

java.util.Locale

VARCHAR

timezone

java.util.TimeZone

VARCHAR

currency

java.util.Currency

VARCHAR

2. OR映射---实体映射示例

*.hbm.xml, 主体内容包含表/类映射, id映射, 属性字段映射三个部分.示例文件:
 
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE hibernate-mapping PUBLIC
 
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
 
  <class name="cn.thinkmore.hibernate.pojo.Tuser" table="T_user">
 
     <id column="id" name="id"  type="java.lang.Integer">
 
         <generator class="increment" />
 
     </id>
 
     <property column="name" name="name" type="java.lang.String"/>
 
  </class>
 
</hibernate-mapping>
 
XML文件头定义了文件的编码方式, DTD与Hibernate的版本有关, 上面是使用hibernate 3.x使用的DTD.
 
3.   OR映射---表/类映射
 
<class name="cn.thinkmore.hibernate.pojo.Tuser" table="T_user">
 
name: 指定了Java数据封装的POJO类类型.
 
table: 指定了数据库的表名
 
4.   OR映射---id映射
 
<id name="id" type="java.lang.Integer" column="id">
 
     <generator class="increment" />
 
</id>
 
name: 指定了映射POJO类的属性名,
 
type: POJO类中属性的数据类型;
 
column: 数据库表的主键字段;
 
generator子元素:由其class属性指定主键生成方式:
 •assigned: 主键由应用程序产生, 不需要hibernate干预
 •identity: 使用数据库的主键生成机制, 如MySQL, DB2、SQL Server的自增主键.
 •sequence: 使用数据库的sequence机制, 如Oracle的sequence
 •uuid.hex: 由Hibernate基于128位唯一值产生算法, 根据ip, 时间, jvm启动时间, 内部自增量生成十六进制的数值, 编码后成为一个32位长的字符串. 该方法提供了最好的数据库插入性能和数据库平台适应性.
 •uuid.string: 与uuid.hex类似, 只是生成的主键没有进行编码, 只有16位长度. 在某些数据库可能出错.
 •hilo: 通过hilo算法实现主键生成, 需要额外的数据库表保存主键生成历史状态.
 •seqhilo: 与hilo类似, 只是主键历史状态保存在sequence中, 适用于支持sequence的数据库.
 •increment: 主键按数值递增, 但如果多个实例同时访问同一个数据库, 各自生成主键,则容易造成主键重复. 
•native: 由hibernate根据数据库适配器中的定义, 自动采用identity, hilo, sequence中的一种方式.
 •foreign: 外部表的字段作主键.
 •select: hibernate 3 中新增的.需要提供一个唯一的标识字段进行二次读取, 以获取触发器生成的主键值, 通过param子元素进行定义, 比如:
 
 
 
<generator class="select">
 
    <param name="key">key_field</param>
 
</generator>
 
   该方法主要针对遗留系统的改造工程, 一些早期的系统主键依赖于触发器生成. 当数据库insert时, 触发器捕获这一操作, 并为主键赋值, 在插入数据库后, 再次读取某一识别字段读取已经插入的数据, 获取其主键值.
 
5.   OR映射---复合主键映射(composite-id)---实体属性组成主键
 
复合主键使用<composite-id>将取代id元素, 并具有property属性列表. 

<composite-id>
 
      <key-property column="userid" name="userid" type="java.lang.String" />
 
      <key-property column="when" name="when" type="java.sql.Date" />
 
    </composite-id>
 
复合主键的POJO类需要实现equals和hashcode方法, 可以使用apache commons lang包中的工具类实现(commons-lang.jar), 比如:
 
 
 
import org.apache.commons.lang.builder.EqualsBuilder;
 
import org.apache.commons.lang.builder.HashCodeBuilder;
 
import org.apache.commons.lang.builder.ToStringBuilder;
 
 
 
...
 
 
 
public String toString(){
 
    return new ToStringBuilder(this)
 
        .append("userid ", getUserid ())
 
        .append("when", getWhen ())
 
        .toString();
 
  }
 
 
 
  public boolean equals(Object other){
 
    if(!(other instanceof MyPoJoClass)){
 
       return false;
 
    }
 
    MyPoJoClass castOther=( MyPoJoClass)other; 

    return new EqualsBuilder()
 
        .appendSuper(super.equals(other))
 
        .append(this.getUserid (),castOther.getUserid() )
 
        .append(this.getWhen (),castOther.getWhen() )
 
        .isEquals();
 
  }
 
 
 
  public int hashCode(){
 
    return new HashCodeBuilder()
 
        .appendSuper(super.hashCode() )
 
        .append(getUserid ())
 
        .append(getWhen ())
 
        .toHashCode();
 
  }
 
装载复合主键的记录时, 考虑把类对应的对象的主键值填充好后作为load的第二个参数.
 
MyPoJoClass obj = new MyPoJoClass();
 
obj.setUserid(...);
 
obj.setWhen(...);
 
obj=(MyPoJoClass)session.load(MyPoJoClass.class, obj);
 
6.   OR映射---复合主键映射(composite-id)---基于主键类
 
可以用一个独立的类来描述主键, 示例:
 
<composite-id name="keyClassProperty" class="MyPoJoClass">
 
      <key-property column="userid" name="userid" type="java.lang.String" />
 
      <key-property column="when" name="when" type="java.sql.Date" />
 
    </composite-id>
 
此时, 需要定义一个新的类KeyClass来作为主键类, KeyClass实现equals和hashcode方法, 而在POJO中, 使用属性名keyClassProperty来表示主键, 其类类型为KeyClass.
 
7.   OR映射---composite-id其他子节点
 
composite-id除了key-property子节点外, 还具有可选<key-many-to-one>子节点.完整的节点内容:
 
<composite-id name="propertyName" 

class="ClassName" 

unsaved-value="any|none" >
 
 
 
      <key-property column="colum_name" 

name=" propertyName "
 
type="type_name" /> 

...
 
      <key-many-to-one  column=" colum_name " calss=" ClassName "
 
  name=" propertyName " />
 
...
 
    </composite-id>
 
8.   OR映射---属性/字段映射
 
<property name="name" type="java.lang.String" column="name" />
 
name: POJO类的属性名,
 
type: POJO类中属性的数据类型; 如果是字符串,可以省略
 
column: 数据库中的字段名. 如果和属性同名, 可以省略.
 
9.   OR映射---自定义数据类型 UserType, CompositeUserType接口
 
hibernate3 中的为: org.hibernate.usertype(hibernate2中为net.sf包)下面的两个接口: UserType 和 CompositeUserType . 它们提供自定义类型的规范, 这里以UserType为例.
 
package org.hibernate.usertype;
 
 
 
import java.io.Serializable;
 
import java.sql.PreparedStatement;
 
import java.sql.ResultSet;
 
import java.sql.SQLException;
 
 
 
import org.hibernate.HibernateException;
 
 
 
public interface UserType {
 
 
 
     /**
 
* 返回本类型所映射的SQL类型, 返回的是int[]数组. 可以取java.sql.Types中的int静态常量. 

* 比如有: public final static int DOUBLE  =   8;
 
      */
 
     public int[] sqlTypes();
 
 
 
     /**
 
      * 定义本类型的nullSafeGet() 方法返回的数据的类型
 
      */
 
     public Class returnedClass();
 
 
 
     /**
 
* 定义两个数据的比较方法, 返回true表示相等, false表示不等.
 
      */
 
     public boolean equals(Object x, Object y) throws HibernateException;
 
 
 
     /**
 
      * Get a hashcode for the instance, consistent with persistence "equality"
 
      */
 
     public int hashCode(Object x) throws HibernateException;
 
 
 
     /**
 
      * 定义从ResultSet中读取数据并转换成自定义类型的方法, 对数据库null应该考虑
 
    * 参数names 包含了当前自定义类型的映射字段名称
 
      */
 
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)  
 
throws HibernateException, SQLException;
 
 
 
     /**
 
      * Hibernate进行数据保存时被调用的方法
 
      * @param st a JDBC prepared statement
 
      * @param value the object to write, 类型应该是returnedClass()方法返回的Class指定的类型
 
      * @param index statement parameter index
 
      * @throws HibernateException
 
      * @throws SQLException
 
      */
 
     public void nullSafeSet(PreparedStatement st, Object value, int index) 

throws HibernateException, SQLException;
 
     /**
 
      * 自定义的对象复制方法, 用作构造返回对象. 

    * nullSafeGet方法被调用后, Hibernate获得了自定义数据对象, 

* 这个对象成为数据库读出的原始对象, 通过deepCopy方法, Hibernate
 
* 返回一个复本给用户. 脏数据检查时, 如果两个对象不等(equals方法返回false),
 
* 就会执行数据库持久化操作.
 
      * @param value the object to be cloned, which may be null
 
      * @return Object a copy
 
      */
 
     public Object deepCopy(Object value) throws HibernateException;
 
 
 
     /**
 
      * Are objects of this type mutable?
 
      * 本类型实例是否可变
 
      * @return boolean
 
      */
 
     public boolean isMutable();
 
 
 
     /**
 
* 把对象转化为二级缓存中保存. 经常把当前对象对其他对象的引用, 保存为其id值.
 
      * Transform the object into its cacheable representation. At the very least this
 
      * method should perform a deep copy if the type is mutable. That may not be enough
 
      * for some implementations, however; for example, associations must be cached as
 
      * identifier values. (optional operation)
 
      *
 
      * @param value the object to be cached
 
      * @return a cachable representation of the object
 
      * @throws HibernateException
 
      */
 
     public Serializable disassemble(Object value) throws HibernateException;
 
 
 
     /**
 
    * 把二级缓存中获取的数据转换为自定义的对象数据
 
      * Reconstruct an object from the cacheable representation. At the very least this
 
      * method should perform a deep copy if the type is mutable. (optional operation)
 
      *
 
      * @param cached the object to be cached
 
      * @param owner the owner of the cached object
 
      * @return a reconstructed object from the cachable representation
 
      * @throws HibernateException
 
      */
 
     public Object assemble(Serializable cached, Object owner) throws HibernateException;
 
 
 
     /**
 
      * During merge, replace the existing (target) value in the entity we are merging to
 
      * with a new (original) value from the detached entity we are merging. For immutable
 
      * objects, or null values, it is safe to simply return the first parameter. For
 
      * mutable objects, it is safe to return a copy of the first parameter. For objects
 
      * with component values, it might make sense to recursively replace component values.
 
      *
 
      * @param original the value from the detached entity being merged
 
      * @param target the value in the managed entity
 
      * @return the value to be merged
 
      */
 
     public Object  replace(Object original, Object target, Object owner)
 
 throws HibernateException;
 
}
 
 
 
如果一个用户具有多个email, 可以分别定义多个字段保存, 也可以定义一个子表专门保存, 但都有点大动干戈. 可以考虑用一个字符串字段保存, 相邻的email用一个;隔开. 比如:
 
package cn.thinkmore.hibernate.pojo;
 
 
 
import java.io.Serializable;
 
import java.sql.PreparedStatement;
 
import java.sql.ResultSet;
 
import java.sql.SQLException;
 
import java.sql.Types;
 
import java.util.*;
 
 
 
import org.hibernate.Hibernate;
 
import org.hibernate.HibernateException;
 
import org.hibernate.usertype.UserType;
 
 
 
public class EmailList implements UserType {
 
 
 
     private static final String SPLITTER = ";";
 
 
 
     private static final int[] TYPES = new int[] { Types.VARCHAR };
 
 
 
     public Object assemble(Serializable cached, Object owner)
 
                   throws HibernateException {
 
            return null;
 
     }
 
 
 
     public Object deepCopy(Object value) throws HibernateException {
 
            if (!(value instanceof List)) {
 
                   return null;
 
            }
 
            List src = (List) value;
 
            List tar = new ArrayList();
 
            tar.addAll(src);
 
            return tar;
 
     }
 
 
 
     public Serializable disassemble(Object value) throws HibernateException {
 
            return null;
 
     }
 
 
 
     public boolean equals(Object x, Object y) throws HibernateException {
 
            if (x == y)
 
                   return true;
 
            if (x != null && y != null) {
 
                   List xList = (List) x;
 
                   List yList = (List) y;
 
                   if (xList.size() != yList.size())
 
                          return false;
 
                   for (int i = 0; i < xList.size(); i++) {
 
                          String strX = xList.get(i).toString();
 
                          String strY = yList.get(i).toString();
 
                          if (!strX.equals(strY))
 
                                 return false;
 
                   }
 
            }
 
            return false;
 
     }
 
 
 
     

     public boolean isMutable() {
 
            return false;
 
     }
 
 
 
     public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
 
                   throws HibernateException, SQLException {
 
            String value = Hibernate.STRING.nullSafeGet(rs, names[0]).toString();
 
            if(null!=value)
 
                   return parse(value);
 
            return null;
 
     }
 
 
 
     private List parse(String value) {
 
        String[] strs = org.apache.commons.lang.StringUtils.split(value,SPLITTER);
 
            List<String> emails = new ArrayList<String>();
 
            for(int i=0; i<strs.length;i++){
 
                   emails.add(strs[i]);
 
            }
 
        return emails;
 
     }
 
     

     private String assemble(List list) {
 
            StringBuilder sb = new StringBuilder();
 
            int maxIndex = list.size()-1;
 
            for(int i=0; i<maxIndex;i++){
 
                   sb.append(list.get(i)).append(SPLITTER);
 
            }
 
            if(0<=maxIndex){
 
                   sb.append(list.get(maxIndex));
 
            }
 
            return sb.toString();
 
     }
 
     

     public void nullSafeSet(PreparedStatement st, Object value, int index)
 
                   throws HibernateException, SQLException {
 
         if(null!=value&&(value instanceof List)){
 
                String str = assemble((List)value);
 
                Hibernate.STRING.nullSafeSet(st,str,index);
 
         }else if(null!=value){
 
                Hibernate.STRING.nullSafeSet(st,value.toString(), index);
 
         }else{
 
                Hibernate.STRING.nullSafeSet(st,null, index);
 
         }
 
     }
 
 
 
     public Object replace(Object original, Object target, Object owner)
 
                   throws HibernateException {
 
            return null;
 
     }
 
 
 
     public Class returnedClass() {
 
            return List.class;
 
     }
 
 
 
     public int[] sqlTypes() {
 
            return TYPES;
 
     }
 
 
 
     public int hashCode(Object x) throws HibernateException {
 
            return 0;
 
     }
 
}
 
数据关联关系
 
数据关联关系在实体的子类里面不会被自动继承.
 
10. 一对一关联 ----- 主键关联 one-to-one
 
一对一的主键关联, 指两个表的记录是一对一的关系, 且一个表的主键取为另一个表对应的记录的主键.
 
<hibernate-mapping>
 
    <class name="cn.thinkmore.hibernate.pojo.Citizen" table="citizen" lazy="true">
 
       <id name="id" column="id">      

           <generator class="uuid.hex" />
 
       </id>
 
       <property name="name" />
 
       <property name="sex"/>
 
       <property name="idcard" />
 
       <property name="address"/>
 
        <one-to-one name="gene"  cascade="all"  outer-join="true" 

                   class="cn.thinkmore.hibernate.pojo.Gene" />
 
    </class>
 
</hibernate-mapping>
 
 
 
name: 属性名
 
class: java全路径类名
 
cascade: 是否级连操作, all , none
 
outer-join: 是否外链接, true/false
 
<hibernate-mapping>
 
    <class name="cn.thinkmore.hibernate.pojo.Gene" table="gene" lazy="true">
 
       <id name="id" column="id" >     

           <generator class="foreign">
 
             <param name="property">citizen</param>
 
           </generator>
 
       </id>
 
       <property name="dna" />
 
       <property name="chromosome"/>
 
       <property name="species"/>
 
       <one-to-one name="citizen"  constrained="true" 

                   class="cn.thinkmore.hibernate.pojo.Citizen" />
 
    </class>
 
</hibernate-mapping>
 
 
 
Constrained: 次关联中的约束方.
 
.....
 
Session s = HibernateSession3.getSession();      

       Citizen one = new Citizen();
 
       one.setIdcard("123456789012345678");
 
       one.setName("Mike");
 
       one.setSex("M");
 
       Gene gene = new Gene();
 
       gene.setBloodType("AB");
 
       gene.setDna("Ajodjjd[[joa");
 
       gene.setSpecial("White");
 
 
 
       one.setGene(gene);
 
       gene.setCitizen(one);
 
 
 
       Transaction trans = s.beginTransaction();
 
       s.saveOrUpdate(one);
 
       trans.commit();
 
 
 
       // 两条数据一起被保存, 查询时也会关联查出来.
 
       Query query = s.createQuery("From  Citizen");
 
       List list = query.list();
 
       for (int i = 0; i < list.size(); i++) {
 
           one = (Citizen) list.get(i);
 
           if (null == one)
 
              continue;
 
           gene = (Gene) one.getGene();
 
           if (null != gene){
 
            System.out.println(gene.getId()+":"+gene.getSpecial()+":"+gene.getDna());
 
           }
 
}
 
11. 单向一对多关联 ----- 唯一外键关联 one-to-many
 
 
 
一个用户可以多个email:
 
 
 
<set name="email" table="emails" cascade="all">
 
    <key column="userid" />
 
<one-to-many calss="....Email" />
 
</set>
 
 
 
12. 双向一对多关联
 
 
 
除了在主控方配置一对多, 还要在被控方配置对应的多对一关系:
 
 
 
User:
 
<set name="email" table="emails" cascade="all" inverse="true">
 
    <key column="userid" />
 
<one-to-many calss="....Email" />
 
</set>
 
 
 
Email:
 
<many-to-one  name="user" class=".....User" cascade="none" column="userid" />
 
 
 
再有例子:一个职员(是人的子类)前后可能有多条工作(每次工作是一条记录):
 
<hibernate-mapping >
 
    <class name="webapp.hibernate.pojo.People" table="people" lazy="false">
 
       <comment>Users may bid for or sell auction items.</comment>
 
       <id name="id">     

           <generator class="uuid.hex"/>
 
       </id>  

       <property name="name" /> 

       <property name="idcard" />  

       <property name="sex"/>             

       <property name="birth" type="date"/>
 
       

        <one-to-one name="gene" 

                    cascade="all" 

                     class="webapp.hibernate.pojo.Gene"/>              

    </class>   

</hibernate-mapping>
 
 
 
<hibernate-mapping >
 
    <class name="webapp.hibernate.pojo.Employee" table="people" lazy="false">
 
       <id name="id">     

           <generator class="uuid.hex"/>
 
       </id>  

       <property name="name" /> 

       <property name="idcard" />  

       <property name="sex"/>             

       <property name="birth" type="date"/>
 
       <one-to-one name="gene" 

                    cascade="all" 

                     class="webapp.hibernate.pojo.Gene"/>    

                     

       <set name="jobs" table="joblist" cascade="all" inverse="true">
 
            <key column="empid" />
 
            <one-to-many class="webapp.hibernate.pojo.JobList" />   

       </set>                  

    </class>   

</hibernate-mapping>
 
 
 
<hibernate-mapping >
 
    <class name="webapp.hibernate.pojo.JobList" table="joblist" lazy="false">
 
       <id name="id">     

           <generator class="uuid.hex"/>
 
       </id>  

<!--       <property name="userid" column="empid"/> -->  

       <property name="company" /> 

       <property name="begin" type="date"/>             

       <property name="end" type="date"/>
 
       <many-to-one  name="employee" class="webapp.hibernate.pojo.Employee" cascade="none" column="empid" />        

    </class>   

</hibernate-mapping>
 
public static void testOne2Many() {
 
       Session s = HibernateSession3.getSession();
 
       Employee e = new Employee();
 
       e.setName("一对多");
 
       e.setIdcard("123456789012345678");
 
       e.setBirth(new java.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*25));
 
       

       JobList job1 = new JobList();
 
       job1.setEmployee(e);
 
       job1.setCompany("A gongsi");
 
       job1.setBegin(new java.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*5));
 
       job1.setEnd(new java.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*4));
 
       

       JobList job2 = new JobList();
 
       job2.setEmployee(e);
 
       job2.setCompany("B gongsi");
 
       job2.setBegin(new java.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*4));
 
       job2.setEnd(new java.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*2));
 
       

       Set<JobList> jobs = new HashSet<JobList>();
 
       jobs.add(job1);
 
       jobs.add(job2);
 
       e.setJobs(jobs);
 
       

 
 
       Transaction trans = s.beginTransaction();
 
       // 两个表的数据一起被保存, 查询时也会关联查出来.
 
       s.saveOrUpdate(e);
 
       trans.commit();
 
 
 
 
 
       Query query = s.createQuery("From Employee");
 
       List list = query.list();
 
       for (int i = 0; i < list.size(); i++) {
 
           Employee one = (Employee) list.get(i);
 
           if (null == one)
 
              continue;
 
           System.out.println(one.getName()+":"+one.getBirth()+":");
 
           Set joblist = one.getJobs();
 
           for(Object o:joblist){          

              JobList j = (JobList)o;
 
              System.out.println("\t工作:"+j.getCompany()+":"+j.getBegin()+":"+j.getEnd());
 
           }
 
           System.out.println("---------------------------------------");
 
       }
 
 
 
    }
 
 
 
13. 双向多对多关联
 
一个用户可以在银行有多个帐号
 
User:
 
    <class name="webapp.hibernate.pojo.MoneyUser" table="people" lazy="false">
 
       <id name="id">     
 
           <generator class="uuid.hex"/>
 
       </id>  

       <property name="name" /> 

       <property name="idcard" />  

       <property name="sex"/>             

       <property name="birth" type="date"/>
 
       

        <one-to-one name="gene" 

                    cascade="all" 

                     class="webapp.hibernate.pojo.Gene"/> 

         <set name="banks" table="bankuser" cascade="none" >
 
            <key column="userid" />
 
            <many-to-many class="webapp.hibernate.pojo.Bank" column="bankid" />  

         </set> 

    </class>   

 
 
Bank:
 
<class name="webapp.hibernate.pojo.Bank" table="bank" lazy="false">
 
       <comment>Users may bid for or sell auction items.</comment>
 
       <id name="id">     

           <generator class="uuid.hex"/>
 
       </id>  

       <property name="bankname" />    

       <property name="type"/>            

       <property name="createday" type="date"/>
 
        <set name="cutomers" table="bankuser" cascade="none" >
 
            <key column="bankid" />
 
            <many-to-many class="webapp.hibernate.pojo.MoneyUser" column="userid" />  

         </set> 

    </class>   

 
 
    public static void testMany2Many() {
 
       Session s = HibernateSession3.getSession();
 
       Iterator<MoneyUser> itor =(Iterator<MoneyUser>)s.createQuery("FROM MoneyUser").iterate();
 
       while(itor.hasNext()){
 
           MoneyUser moneyUser =  itor.next();
 
           Set banks = moneyUser.getBanks();
 
           Iterator<Bank> bankItor = banks.iterator();
 
           while(bankItor.hasNext()){
 
              Bank bank = bankItor.next();
 
              System.out.println(moneyUser.getName()+"  "+bank.getBankname());
 
           }
 
       }
 
    }
 
    

    public static void testMany2Many2() {
 
       Session s = HibernateSession3.getSession();
 
       Iterator<Bank> itor = s.createQuery("FROM Bank").iterate();
 
       while(itor.hasNext()){
 
           Bank bank =  itor.next();
 
           Set customers = bank.getCutomers();
 
           Iterator<MoneyUser> customerItor = customers.iterator();
 
           while(customerItor.hasNext()){
 
              MoneyUser moneyUser = customerItor.next();
 
              System.out.println(bank.getBankname()+"  "+moneyUser.getName());
 
           }
 
       }
 
    }

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/69471.html