Hibernate多对多单向关联和双向关联 --Hibernate框架
Hibernate关联关系中相对比较特殊的就是多对多关联,多对多关联与一对一关联和一对多关联不同,多对多关联需要另外一张映射表用于保存多对多映射信息。本例介绍多对多单向关联和双向关联。单向关联 :指具有关联关系的实体对象间的加载与访问关系是单向的。即,只有一个实体对象可以加载和访问对方,但对方是看不到另一方的。双向关联:双向关联是指具有关联关系的实体对象间的加载与访问关系是双向的。即,任何一方均可加载和访问另一方。
一、多对多单向关联
1、首先创建一个数据库,一条SQL语句搞定
create database many_to_many;
2、配置hibernate.cfg.xml
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!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">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql:///many_to_many
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</property>
<property name="hibernate.connection.provider_class">
org.hibernate.c3p0.internal.C3P0ConnectionProvider
</property>
<property name="hibernate.current_session_context_class">
thread
</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping resource="com/beans/Course.hbm.xml" />
<mapping resource="com/beans/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
3、创建实体类及其对应的映射文件
Course.java:
package com.beans;
public class Course {
private int cid;
private String cname;
public Course(String cname) {
// TODO Auto-generated constructor stub
this.cname = cname;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
}
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.beans">
<!-- 完成类到表的映射,属性到字段的映射 -->
<class name="Course">
<id name="cid">
<generator class="native" />
</id>
<property name="cname"/>
</class>
</hibernate-mapping>
Student.java:
package com.beans;
import java.util.HashSet;
import java.util.Set;
public class Student {
private int sid;
private String sname;
private Set<Course> courses;
public Student(String sname) {
this();
this.sname = sname;
}
public Student() {
// TODO Auto-generated constructor stub
courses = new HashSet<Course>();
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
}
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.beans">
<!-- 完成类到表的映射,属性到字段的映射 -->
<class name="Student">
<id name="sid">
<generator class="native" />
</id>
<property name="sname"/>
<set name="courses" cascade="save-update" table="middle" inverse="false">
<key column="studentId" /><!-- 指定当前类在中间表对应的外键 -->
<many-to-many class="Course" column="courseId"/><!-- 指定关联类在中间表中对应的外键 -->
</set>
</class>
</hibernate-mapping>
4、编写测试类
MyTest.java:
package com.test;
import org.hibernate.Session;
import org.junit.Test;
import com.beans.Course;
import com.beans.Student;
import com.utils.HbnUtils;
public class MyTest {
@Test
public void test01() {
Session session = HbnUtils.getSession();//HbnUtils为封装好的工具类
try {
session.beginTransaction();//开启事务
Course course1 = new Course("struts2");
Course course2 = new Course("hibernate5");
Course course3 = new Course("spring4");
Course course4 = new Course("mybatis");
Student student1 = new Student("Thanlon");
Student student2 = new Student("Tom");
student1.getCourses().add(course1);
student1.getCourses().add(course2);
student1.getCourses().add(course3);
student1.getCourses().add(course4);
student2.getCourses().add(course1);
student2.getCourses().add(course2);
student2.getCourses().add(course3);
session.save(student1);
session.save(student2);
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
测试结果:
课程表:

学生表:

中间表:

二、多对多双向关联
1、接着上面的,可修改Course类如下。
Course.java:
package com.beans;
import java.util.HashSet;
import java.util.Set;
public class Course {
private int cid;
private String cname;
private Set<Student> students;
public Course(String cname) {
this();
this.cname = cname;
}
public Course() {
// TODO Auto-generated constructor stub
students = new HashSet<Student>();
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
}
2、映射文件可做如下修改
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.beans">
<!-- 完成类到表的映射,属性到字段的映射 -->
<class name="Course">
<id name="cid">
<generator class="native" />
</id>
<property name="cname" /> <set name="students" cascade="save-update" table="middle" inverse="false">
<key column="courseId" /><!-- 指定当前类在中间表对应的外键 -->
<many-to-many class="Student" column="studentId" /><!-- 指定关联类在中间表中对应的外键 -->
</set>
</class>
</hibernate-mapping>
3、接着是修改测试类:
MyTest.java:
package com.test;
import org.hibernate.Session;
import org.junit.Test;
import com.beans.Course;
import com.beans.Student;
import com.utils.HbnUtils;
public class MyTest {
@Test
public void test01() {
Session session = HbnUtils.getSession();
try {
session.beginTransaction();
Student student1 = new Student("Thanlon");
Student student2 = new Student("Tom");
Course course1 = new Course("struts2");
Course course2 = new Course("hibernate5");
Course course3 = new Course("mybatis");
course1.getStudents().add(student1);
course1.getStudents().add(student2);
course2.getStudents().add(student1);
course3.getStudents().add(student2);
session.save(course1);
session.save(course2);
session.save(course3);
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
测试结果:
课程表:

学生表

中间表:

完整项目文件参考:https://pan.baidu.com/s/1g1N-vN9dZ9I-cO9wFSciIg 密码:baae
附:个人网站www.nxl123.cn(后台采用Python Flask框架搭建,2019年1月1日将升级完成并正式上线。哎,本人是学生狗呢!网站做的不好希望大家多多提意见或建议吧!?嘿嘿!……以后SEO什么的还得多向大家学习……)
Hibernate多对多单向关联和双向关联 --Hibernate框架的更多相关文章
- Hibernate中用注解配置一对多双向关联和多对一单向关联
Hibernate中用注解配置一对多双向关联和多对一单向关联 Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射.在Hibernate3.3之前,需单独下载注解 ...
- hibernate多对一单向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)
一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同 ...
- hibernate单向关联与双向关联的区别(原)
今天看着hibernate的关联关系,有点迷糊.这里通过多对一表述一下双向与单向的区别. 多对一: 就是A表中的一个字段是B表的主键.多个A表中的数据可以对应一个B表中的数据,同理,一个B表中的数据可 ...
- Java进阶知识11 Hibernate多对多单向关联(Annotation+XML实现)
1.Annotation 注解版 1.1.应用场景(Student-Teacher):当学生知道有哪些老师教,但是老师不知道自己教哪些学生时,可用单向关联 1.2.创建Teacher类和Student ...
- Java进阶知识08 Hibernate多对一单向关联(Annotation+XML实现)
1.Annotation 注解版 1.1.在多的一方加外键 1.2.创建Customer类和Order类 package com.shore.model; import javax.persisten ...
- Hibernate(九)一对多双向关联映射
上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关 内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映 射,即在 ...
- hibernate多对一单向外键
hibernate多对一单向外键: 描述:
- hibernate多对一单向关联注解方式
多对一单向关联,在多的一方加上一的一方作为外键.在程序里表现为:在多的一方加上一的引用. 小组类Group,用户User: Group: package com.oracle.hibernate; i ...
随机推荐
- 打造性感好用的 VS Code 编辑器
官网: https://code.visualstudio.com/ Blog链接:打造性感好用的VS Code编辑器 主命令框 F1或Ctrl+Shift+P: 打开命令面板.在打开的输入框内,可以 ...
- 浅谈Log4j2日志框架及使用
目录 1.日志框架 2.为什么需要日志接口,直接使用具体的实现不就行了吗? 3.log4j2日志级别 4.log4j2配置文件的优先级 5.对于log4j2配置文件的理解 6.对于Appender的理 ...
- cygwin下如何运行crontab定时脚本?
1. 安装cron服务(如果不能启动,使用管理员身份运行cygwin) cygrunsrv -I cron -p /usr/sbin/cron -a -D -I 是安装 cron是服务名 -p /us ...
- resure挽救笔记本系统和一些相关的操作记录
使用fedora23很久了, 但是感觉不是很流畅, 出现了一些不太稳定的体验, 所以想改到centos7. 因为centos7的很多东西 跟 fedora23 很相近了. 所以应该是无缝过渡 是选择3 ...
- 【问题解决:死锁】Lock wait timeout exceeded; try restarting transaction的问题
执行数据删除操作时一直超时并弹出Lock wait timeout exceeded; try restarting transaction错误 解决办法 1.先查看数据库的事务隔离级别 select ...
- 论文笔记之:Graph Attention Networks
Graph Attention Networks 2018-02-06 16:52:49 Abstract: 本文提出一种新颖的 graph attention networks (GATs), 可 ...
- 【转载】RabbitMQ基础知识
本文转自: https://www.cnblogs.com/dwlsxj/p/RabbitMQ.html 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message ...
- 不消失的 taskeng 黑窗口?
2017-01-06出来不消失的 taskeng 黑窗口? 计划运行某些程序时会出现这种现象.例如: 在计划中运行 a.bat : a.bat 里面的内容:start notepad.exestart ...
- 【Java】【反射】
一,java的核心机制 java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection): Java虚拟机:是运行所有Java程序 ...
- PL/SQL Developer安装配置
选择tool下的perferences 修改下面标记的内容即可