多对多的关联,首先就不同于一对多的关联,在多对多的关联中,两边都是多的一方,所以关系操作在哪边进行,效率都是一样的。
再者,多对多要借助第三张表的联合主键建立关系。在这里,我们也会涉及到使用hibernate自定义的配置文件的方法。
我们就拿学生和课程作为例子,
student类:
private Long sid;
private String sname;
private String sdescription;
private Set<Course> courses;
//省略getter&setter
course类:
private Long cid;
private String cname;
private String cdescription;
private Set<Student> students;
//省略getter&setter
从上面的两个类我们可以看到,在两边都有set集合。
下面是相应的映射文件:
Student.hbm.xml
<class name="cn.ansel.domain.many2many.Student">
<!--
在这里为了书写方便,我们省略掉类型
-->
<id name="sid" length="55">
<generator class="increment"></generator>
</id>
<property name="sdescription" length="55"></property>
<property name="sname" length="55"></property>
<!--
table:第三张表的名字,只有多对多才有这个属性,因为这里采用的是联合主键,要通过第三张表来建立关系
key:外键,在多对多的情况中,在什么配置文件,就用对应的类的主键
many2many:column:关联类的主键
-->
<set name="courses" table="student_course" cascade="save-update">
<key>
<column name="sid"></column>
</key>
<many-to-many class="cn.ansel.domain.many2many.Course" column="cid"></many-to-many>
</set>
</class>
Course.hbm.xml
<class name="cn.ansel.domain.many2many.Course">
<id name="cid" length="55">
<generator class="increment"></generator>
</id>
<property name="cname" length="55"></property>
<property name="cdescription" length="55"></property>
<!--
table:第三张表的名字,只有多对多才有这个属性,因为这里采用的是联合主键,要通过第三张表来建立关系
key:外键,在多对多的情况中,在什么配置文件,就用对应的类的主键
many2many:column:关联类的主键
-->
<set name="students" table="student_course" cascade="save-update">
<key>
<column name="cid"></column>
</key>
<many-to-many class="cn.ansel.domain.many2many.Student" column="sid" ></many-to-many>
</set>
</class>
那么都设置好之后呢,由于我们的项目问题,我们把配置文件放在了跟映射文件一样的包中,所以,在我们使用工具类的时候,加上配置文件的位置和名字
public class hibernateUtil {
// static{
// Configuration configuration=new Configuration();
// configuration.configure();
// sessionFactory=configuration.buildSessionFactory();
//
// }
public static SessionFactory sessionFactory;
public static String url;
/**
* 使用@Before是为了在调用子类的测试方法之前完成对URL的赋值,因为在子类中给URL赋值是使用静态代码块
* 如果在这里也使用静态代码块,在运行的时候,url的值会为null,因为父类的静态代码块优先执行。
*/
@Before
public void init(){
//在我们自定义hibernate配置文件的时候,静态代码块不适用了,
//我们应该把它定义成一个方法,这样就可以在测试类里面我们自己写配置文件的位置及名字,灵活性增强
Configuration configuration=new Configuration();
configuration.configure(url);
sessionFactory=configuration.buildSessionFactory();
}
}
然后在测试类我们是这样写的:
public class testCreateTable extends hibernateUtil {
static{
//使用这样的方式给URL赋值,增强了配置文件存放的位置及名字的灵活性
url="cn/ansel/domain/many2many/hibernate.cfg.xml";
}
@Test
public void testCreateT(){
}
}
运行之后,在数据库中增加了3张表: