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 ...
随机推荐
- \n和\r区别
转载:https://www.cnblogs.com/hq233/p/6389234.html 符号 ASCII码 意义\n 10 换行NL\r ...
- 【Python044--魔法方法:简单定制】
一.简单定制 基本要求: -- 定制一个计时器的类 -- start和stop代表开始计时和停止计时 -- 假设计时器对象t1,print(t1)和直接调用t1均显示结果 -- 当计时器未启动或停止计 ...
- topcoder srm 545 div1
problem1 link 这个可以贪心地从前向后构造.假设当前已经的字符串为$S$,对于一个字符$c$来说,设将$c$加到$S$后得到的新串为$S^{'}$.那么如果$X+Y+Z \ge minIn ...
- Flutter学习指南:UI布局和控件
Flutter学习指南:UI布局和控件 - IT程序猿 https://www.itcodemonkey.com/article/11041.html
- CodeForces 867B Save the problem
B. Save the problem! http://codeforces.com/contest/867/problem/B time limit per test 2 seconds memor ...
- 比较好的一些 ConcurrentHashMap讲解博客
jdk8 https://blog.csdn.net/jianghuxiaojin/article/details/52006118#commentBox jdk7.8 https://crossov ...
- BZOJ5018: [Snoi2017]英雄联盟
Description 正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」.现在,小皮球终于受不 了网友们的嘲讽,决定变强了,他变强的方法就是:买皮肤!小皮球只会玩N个英雄 ...
- Hive安装部署及简单测试 网页《一》
1.首先关闭机器上之前配置的分布式Hadoop 命令: (在hadoop的安装目录中) sbin/stop-dfs.sh 关闭: yarn 命令: sbin/stop ...
- JavaWeb--简单分页技术
分页需要的技术点:1.前台分页标签的使用 2.前台上一页,下一页显示的业务逻辑 3.MSQL用到的语句 limit 4.封装pageBean对象 这个是PageBean用到的 分页公式: int t ...
- 通过sql语句修改表的结构
1.修改表的列名 oracle: ALTER TABLE 表名 RENAME COLUMN 列名 TO 新列名sqlserver:exec sp_rename '[表名].[列名]','[表名].[新 ...