今天接着来弄一下hibernate的多对多关联关系,多对多在生活中还是比较多的,例如学生和课程,教师和学生等。学习了这么一段时间的hibernate越来越觉得hibernate是个好东西,应该说学习这个上手还是比较快的。还是一样,我会一步一步的写这么一个程序。
1.写2个vo类Student和Course
package org.lxh.vo;
import java.util.HashSet;
import java.util.Set;
public class Course {
private int id;
private String coursename;
private Set<Student> student=new HashSet<Student>(); //与其他关联关系不同的是这里的集合必须实例化
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCoursename() {
return coursename;
}
public void setCoursename(String coursename) {
this.coursename = coursename;
}
public Set<Student> getStudent() {
return student;
}
public void setStudent(Set<Student> student) {
this.student = student;
}
}
package org.lxh.vo;
import java.util.HashSet;
import java.util.Set;
public class Student {
private int id;
private String name;
private Set<Course> course=new HashSet<Course>(); //与其他关联关系不同的是这里的集合必须实例化
public int getId() {
return id;
}
public void setId(int 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;
}
}
2.写hibernate映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.annotations">
<class name="org.lxh.vo.Student" table="student">
<id name="id" column="id">
<generator class="increment"/>
</id>
<property name="name" column="name"/>
<set name="course" inverse="true">
<key column="stu_id"/>
<many-to-many class="org.lxh.vo.Course"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.annotations">
<class name="org.lxh.vo.Course" table="course">
<id name="id" column="id">
<generator class="increment"/>
</id>
<property name="coursename" column="coursename"/>
<set name="student" inverse="false">
<key column="course_id"/>
<many-to-many class="org.lxh.vo.Student"/>
</set>
</class>
</hibernate-mapping>
3.写一个Junit测试代码的正确性
package test;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.lxh.vo.Course;
import org.lxh.vo.Student;
import util.HibernateUtil;
public class TestMany2Many {
@org.junit.Test public void save()
{
Session ses=null;
Transaction tr=null;
try{
ses=HibernateUtil.getSession();
tr=ses.beginTransaction();
Course course1=new Course();
course1.setCoursename("java程序设计");
Course course2=new Course();
course2.setCoursename("大学英语");
Student stu1=new Student();
stu1.setName("chenwill3");
Student stu2=new Student();
stu2.setName("chenwill4");
course1.getStudent().add(stu1); //把学生添加到集合里
course1.getStudent().add(stu2);
course2.getStudent().add(stu1);
course2.getStudent().add(stu2);
//stu1.getCourse().add(course1); //把课程添加到集合里
//stu1.getCourse().add(course2);
//stu2.getCourse().add(course1);
//stu2.getCourse().add(course2);
ses.save(stu1); //将student信息保存
ses.save(stu2);
ses.save(course1);
ses.save(course2);
tr.commit(); //将事务提交,否侧数据不会被保存
}catch(Exception e){
e.printStackTrace();
}finally{
if(ses!=null){
ses.close(); //关闭连接,否则会把数据库卡死
}
}
}
@org.junit.Test public void query() //通过课程查询学生姓名
{
Session ses=null;
Transaction tr=null;
try{
ses=HibernateUtil.getSession();
tr=ses.beginTransaction();
Course course=(Course)ses.get(Course.class, 1);
Set<Student> all=course.getStudent();
Iterator<Student> it=all.iterator();
Student stu=null;
while(it.hasNext()){
stu=new Student();
stu=it.next();
System.out.println(stu.getName());
}
tr.commit(); //将事务提交,否侧数据不会被保存
}catch(Exception e){
e.printStackTrace();
}finally{
if(ses!=null){
ses.close(); //关闭连接,否则会把数据库卡死
}
}
}
}
需要解释一下那个inverse="false",在映射文件里这么写就是说,关联关系由该配置文件对应的vo类维护,例如在Course.hbm.xml里写了inverse="false",那么关联关系就由course维护(也就是说被注释的‘把课程添加到集合’的那段代码不用写)。
下面看一下运行效果图
在这里有2张临时表生成,这2个表用来存储外键。
到这里代码就写好了,我学习hibernate时间还不长,如果有什么地方弄错了,大家尽量丢板砖。