Hibernate关系映射之many-to-many
1、建表

2、创建实体类及映射文件
Student.java类
public class Student implements java.io.Serializable {
// Fields
private Integer sid;
private String sname;
private Set<Teacher> teachers=new HashSet<Teacher>();
// Constructors
/** default constructor */
public Student() {
}
/** full constructor */
public Student(String sname) {
this.sname = sname;
}
// Property accessors
public Integer getSid() {
return this.sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return this.sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
使用多对多注解应该是:
@ManyToMany
@JoinTable(name="teacher_student",joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="tid")})
public Set<Teacher> getTeachers() {
return teachers;
}
Teacher.java类
public class Teacher implements java.io.Serializable {
// Fields
private Integer tid;
private String tname;
private Set<Student> students=new HashSet<Student>();
// Constructors
/** default constructor */
public Teacher() {
}
/** full constructor */
public Teacher(String tname) {
this.tname = tname;
}
// Property accessors
public Integer getTid() {
return this.tid;
}
public void setTid(Integer tid) {
this.tid = tid;
}
public String getTname() {
return this.tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
被控方注解是:
@ManyToMany(mappedBy="teachers")
public Set<Student> getStudents() {
return students;
}
Student.hbm.xml
<hibernate-mapping>
<class name="com.db.Student" table="student" catalog="mydb">
<id name="sid" type="java.lang.Integer">
<column name="sid" />
<generator class="native" />
</id>
<property name="sname" type="java.lang.String">
<column name="sname" length="32" />
</property>
<!-- 通过table属性告诉hibernate中间表,cascade指明级联操作的类型,inverse属性说明Student实体类是主控方,负责维护关系表 -->
<set name="teachers" table="teacher_student" cascade="save-update,delete" inverse="false">
<!-- 通过key属性告诉hibernate在中间表里面查询sid值相应的student记录 -->
<key>
<column name="sid" not-null="true" />
</key>
<!-- 通过column项告诉hibernate对teacher表中查找tid值相应的teacher记录 -->
<many-to-many class="com.db.Teacher" column="tid"/>
</set>
</class>
</hibernate-mapping>
Teacher.hbm.xml
<hibernate-mapping>
<class name="com.db.Teacher" table="teacher" catalog="mydb">
<id name="tid" type="java.lang.Integer">
<column name="tid" />
<generator class="native" />
</id>
<property name="tname" type="java.lang.String">
<column name="tname" length="32" />
</property>
<!-- 通过table属性告诉hibernate中间表,cascade指明级联操作的类型,inverse属性说明Teacher实体类是被控方,不负责维护关系表 ,不能触发对象和数据库的同步更新的。-->
<set name="students" table="teacher_student" inverse="true"
cascade="save-update,delete">
<key>
<column name="tid" not-null="true" />
</key>
<many-to-many class="com.db.Student" column="sid" />
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLInnoDBDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/mydb
</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">
MyDBAccount
</property>
<property name="show_sql">true</property>
<mapping resource="com/db/Student.hbm.xml" />
<mapping resource="com/db/Teacher.hbm.xml" />
</session-factory>
</hibernate-configuration>
3、建立测试用例
测试用例一:
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=HibernateSessionFactory.getSession();
Student stu1=new Student();
stu1.setSname("StudentAmy");
Teacher t1=new Teacher();
t1.setTname("TeacherSusan");
Teacher t2=new Teacher();
t2.setTname("TeacherLily");
Teacher t3=new Teacher();
t3.setTname("TeacherMaike");
Set<Teacher> teachers=new HashSet<Teacher>();
teachers.add(t1);
teachers.add(t2);
teachers.add(t3);
stu1.setTeachers(teachers);
session.save(stu1);
session.getTransaction().commit();
}
对应的SQL语句是:
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
测试用例二:
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=HibernateSessionFactory.getSession();
Student stu1=new Student();
stu1.setSname("StudentJhon1");
Student stu2=new Student();
stu2.setSname("StudentLihua1");
Teacher t1=new Teacher();
t1.setTname("TeacherJay1");
t1.getStudents().add(stu1);
t1.getStudents().add(stu2);
session.beginTransaction();
session.save(t1);
session.getTransaction().commit();
}
}
对应的SQL语句是:
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
测试用例三:
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session=HibernateSessionFactory.getSession();
Student stu1=new Student();
stu1.setSname("StudentJhon1");
Student stu2=new Student();
stu2.setSname("StudentLihua1");
Teacher t1=new Teacher();
t1.setTname("TeacherJay1");
t1.getStudents().add(stu1);
t1.getStudents().add(stu2);
stu2.getTeachers().add(t1);
session.beginTransaction();
session.save(t1);
session.getTransaction().commit();
}
}
对应的SQL语句是:
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
通过测试用例发现,两个实体类都进行了级联操作,但是只有将Teacher实体对象添加到Student的teachers属性集合中时才能更新维护中间表。因为Student中的teachers集合的inverse属性是false,使得Student类成为主控方,负责维护关联关系;而Teacher中的students集合的inverse属性为true,使得Teacher类成为被控方,不会维护关联关系。
Hibernate关系映射之many-to-many的更多相关文章
- Hibernate学习笔记-Hibernate关系映射
1. 初识Hibernate——关系映射 http://blog.csdn.net/laner0515/article/details/12905711 2. Hibernate 笔记8 关系映射1( ...
- 【SSH 基础】浅谈Hibernate关系映射(4)
继上篇博客 多对多关联映射(单向) 多对多对象关系映射,须要增加一张新表完毕基本映射. Hibernate会自己主动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联,多 ...
- web进修之—Hibernate 关系映射(3)
概述 Hibernate的关系映射是Hibernate使用的难点或者是重点(别担心,不考试哦~),按照不同的分类方式可以对这些映射关系做一个分类,如: 按对象对应关系分: 一对一 多对一/一对多 多对 ...
- Hibernate关系映射时出现的问题
在学习Hibernate框架的关系映射时,遇到了一个问题: INFO: HHH000422: Disabling contextual LOB creation as connection was n ...
- hibernate关系映射
多对一:比如多个订单对应同一个用户,需要在订单表中添加一个用户的属性 订单类: private Integer orderId; private Date createTime; private Us ...
- Hibernate关系映射(注解)
1.类级别注解 @Entity 映射实体类 @Table 映射数句库表 @Entity(name="tableName") - 必须,注解将一个类声明为一个实体bea ...
- Hibernate关系映射(三) 多对多
一.使用用户User和Role实现多对多的示例 User.java,实现对Role的引用 package com.lxit.entity; import java.util.HashSet; impo ...
- Hibernate关系映射(三) 多对一和一对多
一.多对一 学生Student和班级Grade实现多对一,多个学生对应一个班级. Student.java实体类,映射了班级的属性. package com.lxit.entity; import j ...
- Hibernate关系映射(二) 基于外键的双向一对一
基于外键的双向一对一关联映射 需要在一端添加<one-to-one>标签,用property-ref来指定反向属性引用. 还是通过刚才用户和地址来演示双向一对一关联. 代码演示 一.实体类 ...
随机推荐
- Navicat查询哪些表有指定字段名
通常需要查询某个字段来自于哪张表,在navicat中没有直接查哪些表有指定字段名的功能,只能用sql来查. 1.(按字段名查表)查询哪些表有指定字段名(比如查字段名article_id)的SQL: S ...
- MySQL、PHP入门
登录MySQL mysql -hlocalhost-uroot -proot 退出MySQL exit 每条语句后必须加分号:----------------------------- ...
- Ubuntu 发行版的 Linux 操作系统
Ubuntu 发行版的 Linux 操作系统.. ------------------------------------- ------------------------------------- ...
- spring boot整合jsp的那些坑(spring boot 学习笔记之三)
Spring Boot 整合 Jsp 步骤: 1.新建一个spring boot项目 2.修改pom文件 <dependency> <groupId>or ...
- .NET Core多平台开发体验[1]: Windows
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
- nvm版本控制以及node.js
nvm node.js版本控制工具 下载 nvm 包 地址:https://github.com/coreybutler/nvm-windows/releases 我们选择第一个:nvm-noinst ...
- beanshell postprocessor解决编码
beanshell postprocessor String s=new String(prev.getResponseData(),"UTF-8"); char ...
- 最近完成的AndroidStudio项目实现思路及应用技术
主要内容: Android Studio的介绍 AS中个Gradle及Groovy介绍 AS中的依赖管理 Maven以及Nexus私库管理依赖 Gradle对变种代码的管理以及多渠道打包 eclips ...
- 【DDD】领域驱动设计精要
本文算是<领域驱动设计>这本书的读书笔记,加上自己的一些读后感.网上有很多这本书的读书笔记,但是都是别人的,不如自己总结的理解深刻.建议大家在读这本书时结合<实现领域驱动设计> ...
- epoll全面讲解:从实现到应用
多路复用的适用场合 • 当客户处理多个描述符时(例如同时处理交互式输入和网络套接口),必须使用I/O复用. • 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用 ...