hibernate 多对多关系映射

学生 和 课程就是一种多对多的关系映射,那么再hibernate中,对于多对多关系在怎么配置?

和一些注意的事项?简单测试下。

  1. 建表
  2. 实体
  3. 配置文件和映射
  4. 测试

1。使用oracle ,建表sql

create table students(
	id number(7) primary key,
  name nvarchar2(20),
  age number(2)
)

create table course(
	id number(7) primary key,
  name nvarchar2(20),
  time nvarchar2(20)
)

create table st_cou(
	st_id references students(id),
  cou_id references course(id),
  primary key (st_id,cou_id)
)

2. students 实体

package com.hibernate.entity;

import java.util.HashSet;
import java.util.Set;

public class Students {
	private Integer id;
	private String name;
	private Integer age;

	private Set<Course> course = new HashSet<Course>();

	public Integer getId() {
		return id;
	}

	public void setId(Integer 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> getCourse() {
		return course;
	}

	public void setCourse(Set<Course> course) {
		this.course = course;
	}

	public Students(Integer id, String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public Students() {
		super();
	}

	@Override
	public String toString() {
		return "Students [id=" + id + ", name=" + name + ", age=" + age + ", course=" + course + "]";
	}

}

3. course实体

package com.hibernate.entity;

import java.util.HashSet;
import java.util.Set;

public class Course {
	private Integer id;
	private String name;
	private String time;

	private Set<Students> students = new HashSet<Students>();

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public Set<Students> getStudents() {
		return students;
	}

	public void setStudents(Set<Students> students) {
		this.students = students;
	}

	public Course(Integer id, String name, String time) {
		super();
		this.id = id;
		this.name = name;
		this.time = time;
	}

	public Course() {
		super();
	}

	@Override
	public String toString() {
		return "Course [id=" + id + ", name=" + name + ", time=" + time + "]";
	}

}

4.hibernate.cfg.xml 配置

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
    	<!-- 添加配置信息:数据库连接参数 -->
		<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
		<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
		<property name="hibernate.connection.username">zt</property>
		<property name="hibernate.connection.password">zt</property>

		<!-- 添加配置信息:hibernate 自身属性
			dialect :方言,指定数据类型,hibernate可以针对不同的数据库做出相应的优化
		 -->

		<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
		<property name="hibernate.show_sql">true</property>
		<property name="hibernate.format_sql">true</property>

		<!-- 为getCurrentSession增加配置 -->
		<property name="current_session_context_class">thread</property>

		<mapping resource="course.cfg.xml"/>
    </session-factory>
</hibernate-configuration>

course.hbm.xmc 映射配置

<?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="com.hibernate.entity">

	<class name="Students" table="students">
		<id name="id">
			<generator class="increment"></generator>
		</id>

		<property name="age"/>
		<property name="name"/>

		<!-- name:是实体中关联的另一方属性    
		 	cascade:是级联级别
		 	table:是 学生和 课程中间关联的那张表
		 	下面course配置和students配置是一样的。
		 -->
		<set name="course" cascade="all" table="st_cou">
			<!-- columun:是关系表中的自己的维护字段 -->
			<key column="st_id"></key>
			<!-- class:是关系对方的实体
				column:是关系对方的维护字段
			 -->
			<many-to-many class="Course" column="cou_id"/>
		</set>
	</class>

	<class name="Course" table="course">
		<id name="id">
			<generator class="increment"></generator>
		</id>

		<property name="name"/>
		<property name="time"/>
		 
		<set name="students" cascade="all" table="st_cou">
			<key column="cou_id"></key>
			<many-to-many class="Students" column="st_id"></many-to-many>
		</set>
	</class>
</hibernate-mapping>

5. 测试

查询和更新测试略

查询直接查就可以了,更新查询后,修改值后,更新就可以了。

插入测试,级联插入

@Test
	public void inset(){
		Session session = HibUtil.getSession();
		Transaction tx = session.beginTransaction();

		Course course = new Course(null, "地理", "面貌");
		Students students = new Students(null, "蛋蛋", 18);

		students.getCourse().add(course);
		// course.getStudents().add(students);这句不用写
		session.save(students);
		tx.commit();
	}

多对多中,插入,只要乙方进行维护就可以,如果二方都写

students.getCourse().add(course);
course.getStudents().add(students);

那么插入中,再关联表中,由于乙方已经维护,此时已经存在关联关系,这时候,另一方已进行维护

那么由于已经存在关联关系,这时候会报 违反唯一约束条件

删除测试

@Test
	public void delete(){
		Session session = HibUtil.getSession();
		Transaction tx = session.beginTransaction();
		Students students = (Students)session.get(Students.class, 1);
		session.delete(students);
		tx.commit();
	}

执行之后,进入数据库查询,发现,只要是在关联表中存在的,相关学生和课程都会被删除。

配置中,我们配置了级联级别是 all 这中权限过大,慎用。级联级别修改为 save-update

6.注意

1.实体中 我们写关系一方有

private Set<Course> course = new HashSet<Course>();

为什么 new HashSet<Course>();

当我们进行单个插入表时,如果没有new HashSet<Course>();

Students students = (Students)session.get(Students.class, 1);
Course course = new Course(null, "地理", "面貌");

这里的course.getStudents() 是个null 而用null对象.add 会是空指针
course.getStudents().add(students);
		

2. 级联关系

在关联关系中,要慎用关系,以免对另一方数据操作损失。

时间: 2025-01-06 10:07:46

hibernate 多对多关系映射的相关文章

Hibernate多对多关系映射(建表)

下边讲述Hibernate多对多关系映射. 多对多关系的表的结构为: 两个实体表,还包含一个关系表,关系表为复合主键,如果要使用Hibernate多对多关系映射,则关系表必须只包含两个字段,如果生成了Hibernate多对多关系映射,则中间关系表不会生成实体(即没有对应的pojo类,更没有其映射文件). 1.建立表 DROP TABLE user_course ; DROP TABLE user ; DROP TABLE course ; CREATE TABLE user ( userid  

Hibernate多对多关系映射

两张表的多对多关系,在数据库中通常是通过第三张中间表来实现的,第三张中间表放的是两张表各自的主键值,通过主键与主键的对应来体现表直接的关系.比如在权限系统中,一个用户可以拥有多种权限,而一种权限也可以授予多个用户. 在持久化对象设计的时候,角色和用户都分别有一个集合来防止拥有它的用户或角色.角色类的设计: public class RolePO { private int id;  private String name;  private Set employees = new HashSet

深入浅出Hibernate(二)多对一关系映射

学习Hibernate是为了更方便的操作数据库,在数据库中的关系模型中存在多对一的关系,比如下图所示的员工和部门之间的关系,那么这种关系在Hibernate中如何映射呢?让我用一个小Demo来详细讲解. 建立映射分为以下几步: 1.设计domain对象Department.Employee,代码如下: package cn.itcast.hibernate.domain; public class Department { private int id; private String name;

Hibernate学习笔记(五) — 多对多关系映射

多对多关系映射 多对多建立关系相当于在第三张表中插入一行数据 多对多解除关系相当于在第三张表中删除一行数据 多对多修改关系相当于在第三张表中先删除后增加 多对多谁维护效率都一样.看需求 在实际开发过程中,多对多的映射关系比较常见. 学生选课示例,一个学生可以选多门课,一门课也可以由多个学生去选,这样就形成了多对多的映射关系 public class Student implements Serializable { private static final long serialVersionU

Hibernate自身一对多和多对多关系映射

一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别,新闻包含体育新闻和政治新闻,体育新闻内有含有足球新闻和篮球新闻,其实他们都属于新闻,只是名字不同而已,下面我们就以新闻类别为例来具体说明一下: 首先我们来看一下新闻类别的类图: 类图:category 从上面的图我们可以看出:每一个新闻类别都有一个父类别和一个孩子类别的set集合,这个父类别和孩子

Hibernate映射(二)——多对一关系映射

上篇学习了Hibernate的基本映射,也就是单表映射,很容易就能理解,但是对于关系数据库来说,表之间存在关系是比不可少的,关系数据库中存在的关系是通过主外键建立起来的,反应到Hibernate要如何通过对象表现呢?下面我们就继续学习Hibernate的对象关系映射. 我们先从最常见的多对一和一对多关系开始: 多对一 所谓多对一,在数据库中即在多的一端添加外键关联到一的一端,比如用户(User)和用户所在组(Group)的关系:一个User只属于一个Group,一个Group有多个Group,并

【Java EE 学习第46天】【Hibernate学习第三天】【多对多关系映射】

一.多对多关系概述 以学生和课程之间的关系为例. 1.在多对多关系中涉及到的表有三张,两张实体表,一张专门用于维护关系的表. 2.多对多关系中两个实体类中应当分别添加对方的Set集合的属性,并提供set和get方法. 3.在配置映射文件的时候较一对多关系复杂. 二.映射文件 <set name="students" table="course_stu" cascade="save-update" inverse="true&quo

菜鸟学习Hibernate——一对多关系映射

Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创建实体类Classes和实体类Student Classes.java package com.bjpowernode.hibernate; import java.util.Set; public class Classes { private int id; private String nam

hibernate多对一关联映射

hibernate多对一关联映射: 实体类 (POJO) public class Student{ private int stuId; private String stuNum; private String stuName; private ClassRoom cr; } public class ClassRoom{ private int claId; private String claName; } 映射文件 <class name=" Student" tabl