Hibernate多对多映射(双向关联)实例详解——真

一个学生可以选多门课

一门课程有多个学生上

 

实现步骤:

一、学生

(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

转载于:https://www.cnblogs.com/Donnnnnn/p/7838703.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值