上一篇我说了一下Hibernate一对多关联映射
这一次就说一下Hibernate多对多关联映射
讲个例子来说一下这个多对多关系吧~让我们更好的理解~
实例:一个学生对应多个课程,一个课程对应多个学生~
步骤如下:
1.写出POJO类来
Student类:
public class Student {
private Long id;
private String name;
private Integer age;
//一个学生有好多课程
private Set<Course>courses=new HashSet<Course>();
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(Long id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
Course类:
public class Course {
private Long id;
private String name;
private Integer credit;//学分
//一门课也有好多学生上
private Set<Student>students=new HashSet<Student>();
public Course() {
super();
// TODO Auto-generated constructor stub
}
public Course(Long id, String name, Integer credit) {
super();
this.id = id;
this.name = name;
this.credit = credit;
}
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 Integer getCredit() {
return credit;
}
public void setCredit(Integer credit) {
this.credit = credit;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Course [id=" + id + ", name=" + name + ", credit=" + credit + "]";
}
}
好了,POJO类就这样写好了~
2. 编写映射文件来双向维护表的关系~student.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xu.day5.many2many">
<class name="Student" table="tb_student">
<id name="id" column="id">
<generator class="increment" />
</id>
<property name="name" />
<property name="age" />
<!-- 关联映射 -->
<set name="courses" table="tb_student_course">
<!-- s_id在这里的意思就是让Student知道桥表tb_student_course是谁-是s_id -->
<!-- column="c_id"代表的是对应的类Student在桥表的外键是c_id -->
<key column="s_id" />
<many-to-many class="Course" column="c_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
course.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xu.day5.many2many">
<class name="Course" table="tb_course">
<id name="id" column="id">
<generator class="increment" />
</id>
<property name="name" />
<property name="credit" />
<!-- 关联映射 -->
<!-- table="tb_student_course"代表的是多对多组成了一张新表 -->
<!-- key column="c_id"代表的是要让Course表知道桥表tb_student_course的外键是谁-c_id-->
<!-- column="s_id"代表的是对应的类Course在桥表的外键是s_id -->
<set name="students" table="tb_student_course">
<key column="c_id"/>
<many-to-many class="Student" column="s_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
我就不一一解释了,注释写的很清楚,不懂的可以一起讨论~
3.把映射文件集成到配置文件中~
hibernate.cfg.xml:
写上俩行代码就行:
<mapping resource="com/xu/day5/many2many/student.hbm.xml" />
<mapping resource="com/xu/day5/many2many/course.hbm.xml" />
4.最后写个测试类Main~
模拟几个功能~
(1)学生报名
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=HibernateSessioFactory.getSession();
Transaction tr=session.beginTransaction();
System.out.println(1111111);
//学生报名
Student s1=new Student(null, "张三", 10);
Student s2=new Student(null, "李四", 25);
session.save(s1);
session.save(s2);
tr.commit();
}
}
效果图如下:
(2)录入课程
//录入课程
Course course1=new Course(null, "Java", 2);
Course course2=new Course(null, "c#", 4);
Course course3=new Course(null, "语文", 3);
session.save(course1);
session.save(course2);
session.save(course3);
效果图就不贴了~
(3)学生登录
//学生登录
String hql="from Student where name=?";
Query query=session.createQuery(hql);
query.setString(0, "张三");
Student student=(Student) query.uniqueResult();
(4)查询课程
String hql2="from Course where name=?";
Query query2=session.createQuery(hql2);
query2.setString(0, "c#");
Course course=(Course) query2.uniqueResult();
(5)选课
student.getCourses().add(course);
(6)查询选课
//查询选课
Set<Course>courses=student.getCourses();
for(Course course1:courses){
System.out.println(course1);
}
注意:
在映射元素上反应的是关联关系,由于多对多需要使用桥表来维护关联关系,所以需要在set元素中添加table元素用来指定桥表,key元素中的column属性表示本类在桥表中的外键。many-to-many表示对应的另外一方,其中的column属性表示对应的类在桥表中的外键。
好了,多对多关联映射其实不难,最重要的是要理解~
其实多对多关系还可以简化一点,下篇我再说~