多对多关联也是一种极为常见的关联关系,比如一个学生可以选修多门课程,一门课程也可以有多名学生选修,要实现查询一个学生所选的所有课程的和查询一门课程所有选修的学生就需要用到多对多的关联关系。多对多的基本原理是在数据库中另外创建一张表来管理表与表之间的联系,关键配置为*.hbm.xml文件中的set的配置,用到的标签为:many-to-many 。
以一个学生可以选修多门课程,一门课程也可以有多名学生选修为例:
一、创建多的一端student类
package cn.test.Bean;
import java.util.HashSet;
import java.util.Set;
public class student {
private Long id;
private String name;
private Set<Course> course=new HashSet<Course>();
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<Course> getCourse() {
return course;
}
public void setCourse(Set<Course> course) {
this.course = course;
}
}
其student.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="cn.test.Bean.student" table="student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="course" table="st_cou" cascade="save-update">
<key column="id"></key>
<many-to-many column="cid" class="cn.test.Bean.Course"></many-to-many>
</set>
</class>
</hibernate-mapping>
说明:在映射文件中,使用的set元素对student类中course属性进行配置,name属性为指定属性名,table为指定的连接的表名称,子元素key中,使用colum属性指定连接表中引用student表的外键为id。在many-to-many 元素中,使用class属性指定集合属性course中存储Course类对象,并使用colum元素指定连接表中引用course表的外键为cid。
二、建立多的一端Course类
package cn.test.Bean;
import java.util.HashSet;
import java.util.Set;
public class Course {
private Long cid;
private String cname;
private Set<student> st=new HashSet<student>();
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Set<student> getSt() {
return st;
}
public void setSt(Set<student> st) {
this.st = st;
}
}
其Course.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="cn.test.Bean.Course" table="Course">
<id name="cid">
<generator class="native"></generator>
</id>
<property name="cname"></property>
<set name="st" table="st_cou" cascade="save-update">
<key column="cid"></key>
<many-to-many column="id" class="cn.test.Bean.student"></many-to-many>
</set>
</class>
</hibernate-mapping>
编写测试类,查询所有选修了课程为数学的学生名称
package cn.test.hibernate;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.Test;
import cn.test.Bean.Course;
import cn.test.Bean.student;
public class testnton {
private SessionFactory sessionFactory;
@Test
public void nton()
{
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure() // configures settings from hibernate.cfg.xml
.build();
sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
Session session =sessionFactory.openSession();
student st1=new student();
student st2=new student();
Course c1=new Course();
Course c2=new Course();
c1.setCname("语文");
c2.setCname("数学");
st1.setName("zs");
Set<Course> cc1=new HashSet<Course>();
Set<Course> cc2=new HashSet<Course>();
cc2.add(c2);
cc1.add(c1);
cc1.add(c2);
st2.setName("lisi");
st1.setCourse(cc1);
st2.setCourse(cc2);
session.beginTransaction();
session.save(st1);
session.save(st2);
List<Course> stu=session.createQuery("FROM Course c where c.cname='数学'").list();//得到课程名称数学的课程类
for(int i=0;i<stu.size();i++)
{
Iterator<student> it = stu.get(i).getSt().iterator();//取选修了课程为数学的学生的名字
while(it.hasNext())//判断是否有下一个
{
System.out.println(it.next().getName());
}
}
session.getTransaction().commit();
session.close();
}
}
我们可以打开数据库,数据库中有三张表格,一张为student,一张为Course,还有一张连接表st_cou。