[标题]:Hibernate一对多(双向)
[时间]:2009-6-17
[摘要]:Hibernate一对多双向关联,例如一个用户有多张银行卡。
[关键字]:双向关联,Hibernate,ORM,关系数据库,映射,一对多
[环境]:MyEclipse7 ,Hibernate3.2
[作者]:Winty (
[email protected]) 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框架技术》 : 清华大学出版社