多對(duì)多關(guān)系一般指兩個(gè)類都擁有對(duì)方集合的成員變量,比如說文章類Article和標(biāo)簽類Tag,一個(gè)Arirtle類可以擁有多個(gè)Tag,一個(gè)Tag也適用于多篇文章,它們的類圖如下:
它們也分別對(duì)應(yīng)數(shù)據(jù)庫中的實(shí)體表Articles和Tags,當(dāng)然僅靠這兩個(gè)表實(shí)現(xiàn)多對(duì)多能力是有限的,我們還需要第三個(gè)表ArticleTag的幫忙,它們的ER圖如下:
實(shí)際上多對(duì)多關(guān)系并不復(fù)雜,加入一個(gè)中間表問題就迎刃而解,這和在耦合強(qiáng)烈的兩個(gè)類之間加入一個(gè)中間類以降低耦合的思維是一致的.
下面的代碼演示了如何將兩個(gè)類和數(shù)據(jù)庫映射起來:
Article類:
package com.sitinspring.articletag;

import java.util.HashSet;
import java.util.Set;


public class Article
{
private long id;
private String name;
private Set<Tag> tags = new HashSet<Tag>();

public Article()
{
}

public Article(long id,String name)
{
this.id=id;
this.name=name;
}

public String toString()
{
String retval="Article name="+name;

for(Tag tag:tags)
{
retval+="\n"+tag;
}
return retval;
}


public long getId()
{
return id;
}


public void setId(long id)
{
this.id = id;
}


public String getName()
{
return name;
}


public void setName(String name)
{
this.name = name;
}


public Set getTags()
{
return tags;
}


public void setTags(Set tags)
{
this.tags = tags;
}
}
Article.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 package="org.hibernate.auction">
<class name="com.sitinspring.articletag.Article" table="ARTICLE">
<id name="id" column="ARTICLEID" />
<property name="name" column="NAME" />

<set name="tags" table="ARTICLETAG" cascade="all" lazy="false">
<key column="ARTICLEID" />
<many-to-many column="TAGID" class="com.sitinspring.articletag.Tag" />
</set>
</class>
</hibernate-mapping>
Tag類:
package com.sitinspring.articletag;

import java.util.HashSet;
import java.util.Set;


public class Tag
{
private long id;
private String name;
private Set articles = new HashSet();

public Tag()
{
}

public String toString()
{
return "Tag name="+name;
}

public Tag(long id,String name)
{
this.id=id;
this.name=name;
}


public long getId()
{
return id;
}


public void setId(long id)
{
this.id = id;
}


public java.lang.String getName()
{
return name;
}


public void setName(java.lang.String name)
{
this.name = name;
}


public Set getArticles()
{
return articles;
}


public void setArticles(Set articles)
{
this.articles = articles;
}
}
Tag.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 package="org.hibernate.auction">
<class name="com.sitinspring.articletag.Tag" table="TAG">
<id name="id" column="TAGID" />
<property name="name" column="NAME" />
<set name="articles" table="ARTICLETAG" cascade="all" lazy="false">
<key column="TAGID" />
<many-to-many column="ARTICLEID" class="com.sitinspring.articletag.Article" />
</set>
</class>
</hibernate-mapping>
測試代碼:
package com.sitinspring.articletag;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;

import com.sitinspring.util.HibernateUtil;


public class Main
{

public static void main(String[] args)
{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();

// --插入代碼開始
Article article = new Article(1, "論語學(xué)而");

Set tags = new HashSet();
Tag tag1 = new Tag(8, "軍事");
tags.add(tag1);

Tag tag2 = new Tag(9, "政治");
tags.add(tag2);

article.setTags(tags);

session.save(article);
// --插入代碼結(jié)束

// --讀取代碼開始
long i = 1;

Article articleLoaded = (Article) session.load(Article.class, i);
System.out.println(articleLoaded);
// --讀取代碼開始

session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
}
測試結(jié)果如下:
代碼下載:
http://m.tkk7.com/Files/sitinspring/HibernateClasses20071109085612.rar