随笔 - 117  文章 - 72  trackbacks - 0

声明:原创作品(标有[原]字样)转载时请注明出处,谢谢。

常用链接

常用设置
常用软件
常用命令
 

订阅

订阅

留言簿(7)

随笔分类(130)

随笔档案(123)

搜索

  •  

积分与排名

  • 积分 - 154450
  • 排名 - 389

最新评论

[标题]:Hibernate一对多(双向)
[时间]:2009-6-17
[摘要]:Hibernate一对多双向关联,例如一个用户有多张银行卡。
[关键字]:双向关联,Hibernate,ORM,关系数据库,映射,一对多
[环境]:MyEclipse7 ,Hibernate3.2
[作者]:Winty (wintys@gmail.com) http://www.blogjava.net/wintys

[正文]:
    Hibernate一对多双向关联,例如一个用户有多张银行卡。双向一对多关联在单向一对多(参见"Hibernate一对多(单向)":http://www.blogjava.net/wintys/archive/2009/06/13/hibernate_onetomany.html)的基础上,再对"多"方进行配置。
1、概述
a.实体类:
public class User{
    ...
    private Set<Card> cards;
    ...
}

public class Card{
    ...
    private User user;
    ...
}

b.Hibernate配置文件
根据需要可以将User.hbm.xml中set的属性inverse设置为true
User.hbm.xml:
<set name="cards" inverse="true" cascade="all">
    <key column="userId" />
    <one-to-many class="wintys.hibernate.onetomany.Card" />
</set>

Card.hbm.xml:
<many-to-one   name="user"
                        class="wintys.hibernate.onetomany.User"
                        column="userId"
                        cascade="all" />

c.数据库:
数据库表与单向一对多时并没有区别,还是在"多方"加一个外键"userId"即可。

2、实体类:
User:
package wintys.hibernate.onetomany;

import java.util.Set;

public class User {
    private String id;
    private String name;
    private Set<Card> cards;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void setCards(Set<Card> cards) {
        this.cards = cards;
    }

    public Set<Card> getCards() {
        return cards;
    }   
}

Card:
package wintys.hibernate.onetomany;

public class Card {
    private String id;
    private float balance;
    private User user;/*用于实现反向关联:"多对一"*/
    
    public Card(){
    }
    
    public Card(float balance){
        this.balance = balance;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public float getBalance() {
        return balance;
    }
    public void setBalance(float balance) {
        this.balance = balance;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }   
}


3、映射文件:
用户类映射文件/src/wintys/hibernate/onetomany/User.hbm.xml:
<?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">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
    <class name="wintys.hibernate.onetomany.User" table="myuser" catalog="db">
        <id name="id" type="string">
            <column name="id" not-null="true"/>
            <generator class="uuid.hex" />
        </id>
        <property name="name" type="java.lang.String" column="name" />
        
        <!-- 当用于实现反向关联:"多对一"-->
        <set name="cards" inverse="true" cascade="all">
            <key column="userId" />
            <one-to-many class="wintys.hibernate.onetomany.Card" />
        </set>
    </class>
</hibernate-mapping>


银行卡映射文件/src/wintys/hibernate/onetomany/User.hbm.xml:
<?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">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
    <class name="wintys.hibernate.onetomany.Card" table="mycard" catalog="db">
        <id name="id" type="string">
            <column name="id" not-null="true"/>
            <generator class="uuid.hex" />
        </id>
        <property name="balance" />
        
        <!-- 用于实现反向关联:"多对一" -->
        <many-to-one name="user"
                     class="wintys.hibernate.onetomany.User"
                     column="userId"
                     cascade="all" />
    </class>
</hibernate-mapping>


4、数据库表与"单向一对多"相同。

5、Hibernate配置文件:/src/hibernate.cfg.xml也与"单向一对多"相同。

6、使用测试:
/src/wintys/hibernate/onetomany/HibernateUtil.java与"单向一对多"相同。
/src/wintys/hibernate/onetomany/CardDAO.java:

package wintys.hibernate.onetomany;
import java.util.List;

public interface CardDAO {
    public void insert();
    public List<Card> selectAll();
}


/src/wintys/hibernate/onetomany/CardDAOBean.java:
package wintys.hibernate.onetomany;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class CardDAOBean implements CardDAO {

    public void insert() throws HibernateException {
        Transaction tc = null;
        try{
            Card c1,c2,c3;
            User user;
            Set<Card> cards;
            
            c1 = new Card(7641.96f);
            c2 = new Card(654.8f);
            c3 = new Card(3650f);
            
            user = new User();
            user.setName("Tom");
            
            /*一对多映射*/
            cards = new HashSet<Card>();
            cards.add(c1);
            cards.add(c2);
            cards.add(c3);
            user.setCards(cards);
            
            /*多对一映射*/
            c1.setUser(user);
            c2.setUser(user);
            c3.setUser(user);
            
            Session session = HibernateUtil.getSession();
            tc = session.beginTransaction();
                        
            session.save(c1);
            session.save(c2);
            session.save(c3);
            
            tc.commit();
        }catch(HibernateException e){
            try{
                if(tc != null)
                    tc.rollback();
            }catch(Exception ex){
                System.err.println(ex.getMessage());
            }
            System.err.println(e.getMessage());
        }finally{
            HibernateUtil.closeSession();           
        }
    }

    @SuppressWarnings("unchecked")
    public List<Card> selectAll() throws HibernateException {
        List<Card> cards = null;
        Transaction tc = null;
        try{
            Session session = HibernateUtil.getSession();
            tc = session.beginTransaction();
                        
            Query query = session.createQuery("from Card");
            cards = query.list();
            
            tc.commit();
        }catch(HibernateException e){
            try{
                if(tc != null){
                    tc.rollback();
                    cards = null;
                }
            }catch(Exception ex){
                System.err.println(ex.getMessage());
            }
            System.err.println(e.getMessage());
        }finally{
            //HibernateUtil.closeSession();         
        }
        
        return cards;
    }
}


7、运行结果:

控制台显示:
......
Hibernate: insert into db.myuser (name, id) values (?, ?)
Hibernate: insert into db.mycard (balance, userId, id) values (?, ?, ?)
Hibernate: insert into db.mycard (balance, userId, id) values (?, ?, ?)
Hibernate: insert into db.mycard (balance, userId, id) values (?, ?, ?)
Hibernate: update db.mycard set balance=?, userId=? where id=?
Hibernate: update db.mycard set balance=?, userId=? where id=?
Hibernate: update db.mycard set balance=?, userId=? where id=?
......

id:402881e421eddc240121ede9c5d10009
name:Tom
cards:
    cardId:402881e421eddc240121ede9c5d1000a
    balance:7641.96
    cardId:402881e421eddc240121ede9c5d1000c
    balance:3650.0
    cardId:402881e421eddc240121ede9c5d1000b
    balance:654.8

[参考资料]:
《J2EE项目实训-Hibernate框架技术》 : 清华大学出版社
原创作品,转载请注明出处。
作者:Winty (wintys@gmail.com)
博客:http://www.blogjava.net/wintys

posted on 2009-06-17 22:04 天堂露珠 阅读(482) 评论(0)  编辑  收藏 所属分类: Hibernate

只有注册用户登录后才能发表评论。


网站导航: