一个学生可以选多门课
一门课程有多个学生上
实现步骤:
一、学生
(1)数据库创建学生数据表students,包含id,name字段
设置id字段为主键,类型:bigint,自增
设置name字段,类型:nvarchar(50)
(2)创建Student.java实体类,对应数据表
package com.zit.entities; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.Id; public class Student { private long id; private String name; private Set<Course> courses = new HashSet<Course>(); public Student(){ } 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> getCourses() { return courses; } public void setCourses(Set<Course> courses) { this.courses = courses; } }
(3)创建映射文件Student.hbm.xml,表明映射关系
1、Student.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.zit.entities.Student" table="students"> <id name="id" column="id" type="long" > <generator class="native"/> </id> <property name="name" column="name" type="string"/> <!-- 添加中间表映射 --> <set name="courses" table="students_courses" cascade="save-update" inverse="false"> <key column="student_id"></key> <many-to-many class="com.zit.entities.Course" column="course_id"></many-to-many> </set> </class> </hibernate-mapping>
(1)<class>的name:实体类路径, table:数据表名字 (2)id的<generator class="native"/>:主键生成策略,因为我在数据表已让主键id字段自增,这里设置native(别的百度一下即可) (3)id的column:对应数据表字段id,数据表为bigint类型,对应Java的long类 (4)<set>标签:设置中间表 table:中间表表名, cascade:什么情况下进行关联操作,这里设为save-update,所以save时会进行关联操作 inverse:true/false,由false的一方维护,这里是多对多,双方维护,双方都为false <key column>:对应中间表的字段student_id,指定为students表的id的外键 <many-to-many>:class:它指出与Student类进行关联的类,即Course; column:指定为courses表的主键id的外键
Course.hbm.xml中与之相反即可,具体见下面具体配置
二、课程
(1)数据库创建课程数据表courses,包含id,name字段(与学生表相同即可)
设置id字段为主键,类型:bigint,自增
设置name字段,类型:nvarchar(50)
(2)创建Course.java实体类,对应数据表
package com.zit.entities; import java.util.HashSet; import java.util.Set; public class Course { private long id; private String name; private Set<Student> students = new HashSet<Student>(); public 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<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } }
(3)创建映射文件Course.hbm.xml,表明映射关系
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.zit.entities.Course" table="courses"> <id name="id" column="id" type="long" > <generator class="native"/> </id> <property name="name" column="name" type="string"/> <!-- 添加中间表映射 --> <set name="students" table="students_courses" cascade="save-update" inverse="false"> <key column="course_id"></key> <many-to-many class="com.zit.entities.Student" column="student_id"></many-to-many> </set> </class> </hibernate-mapping>
三、中间表
由Hibernate自动生成中间表,不需自己创建
它是根据Student.hbm.xml和Course.hbm.xml中的映射自动生成对应字段,
student_id字段,是students表的主键id的外键
course_id字段,是courses表的主键id的外键
如下图所示:
四、 测试代码:
(运行后自动生成中间表)
1、一个学生,选了两门课——“语文”、“化学”
2、一门课程,有两个学生——“杨洋1”、“杨洋2”
@Resource(name = "sessionFactory") private SessionFactory sessionFactory; @Override @Transactional public void insert() { //getCurrentSession()比openSession()安全,注意web.xml中的配置,不然会报错 Session session = sessionFactory.getCurrentSession(); Transaction tran = session.beginTransaction(); // 1、王晓东1选了两门课 Student s1 = new Student(); s1.setName("王晓东1"); Course c1 = new Course(); c1.setName("语文"); Course c2 = new Course(); c2.setName("化学"); s1.getCourses().add(c1); s1.getCourses().add(c2); session.save(s1); // 2、英语课有两个学生 // Course c3 = new Course(); // c3.setName("英语"); // Student s2 = new Student(); // s2.setName("杨洋1"); // Student s3 = new Student(); // s3.setName("杨洋2"); // c3.getStudents().add(s2); // c3.getStudents().add(s3); // session.save(c3); tran.commit(); session.flush();// session.close(); }
注意commit后,要flush刷到数据库
我的SessionFactory使用了SSH框架的注解配置 (根据自己的方式来获得Session即可)
SSH框架搭建完整实例参考我的另一篇博客: http://www.cnblogs.com/Donnnnnn/p/7481357.html
实现效果:
1、一个学生,选了两门课——“语文”、“化学”
(1)控制台显示执行的sql语句
Hibernate: insert into students (name) values (?) Hibernate: insert into courses (name) values (?) Hibernate: insert into courses (name) values (?) Hibernate: insert into students_courses (student_id, course_id) values (?, ?) Hibernate: insert into students_courses (student_id, course_id) values (?, ?)
可以看到,往学生表、课程表和中间表都插入了数据
(2)数据库
students表:
courses表:
students_courses表:
2、一门课程,有两个学生——“杨洋1”、“杨洋2”
同上
参考别人博客:
https://www.cnblogs.com/whgk/p/6121593.html