1.schema.sql
alter table student_course drop foreign key FKB0A3729FA6819B7; alter table student_course drop foreign key FKB0A3729FA135F25D; drop table if exists course; drop table if exists student; drop table if exists student_course; create table course (cid integer not null auto_increment, name varchar(255), primary key (cid)); create table student (sid integer not null auto_increment, name varchar(255), primary key (sid)); create table student_course (student_id integer not null, course_id integer not null, primary key (student_id, course_id)); alter table student_course add index FKB0A3729FA6819B7 (student_id), add constraint FKB0A3729FA6819B7 foreign key (student_id) references student (sid); alter table student_course add index FKB0A3729FA135F25D (course_id), add constraint FKB0A3729FA135F25D foreign key (course_id) references course (cid);
表结构如下图所示
2.Hibernate Configure File
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.username">root</property> <property name="connection.password">123456</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="format_sql">false</property> <!-- <mapping resource="org/fool/model/Student.hbm.xml" /> --> <!-- <mapping resource="org/fool/model/Course.hbm.xml" /> --> <mapping class="org.fool.model.Student" /> <mapping class="org.fool.model.Course" /> </session-factory> </hibernate-configuration>
3.Hibernate Model Class
Student.java
package org.fool.model; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; @Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "sid") private int id; @Column(name = "name") private String name; @ManyToMany(fetch = FetchType.LAZY) @Cascade(CascadeType.SAVE_UPDATE) @JoinTable(name = "student_course", joinColumns = { @JoinColumn(name = "student_id") }, inverseJoinColumns = { @JoinColumn(name = "course_id") }) private Set<Course> courses; public int getId() { return id; } public void setId(int 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; } }
以上的Annotation代码就相当于以下的Student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.fool.model.Student" table="student"> <id name="id" column="sid" type="integer"> <generator class="identity"> </generator> </id> <property name="name" column="name" type="string" /> <set name="courses" table="student_course" cascade="save-update"> <key column="student_id"></key> <many-to-many class="org.fool.model.Course" column="course_id"> </many-to-many> </set> </class> </hibernate-mapping>
Course.java
package org.fool.model; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; @Entity @Table(name = "course") public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "cid") private int id; @Column(name = "name") private String name; @ManyToMany(fetch = FetchType.LAZY, mappedBy = "courses") @Cascade(CascadeType.SAVE_UPDATE) private Set<Student> students; public int getId() { return id; } public void setId(int 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; } }
以上的Annotation代码就相当于以下的Course.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.fool.model.Course" table="course"> <id name="id" column="cid" type="integer"> <generator class="identity"> </generator> </id> <property name="name" column="name" type="string" /> <set name="students" table="student_course" cascade="save-update" inverse="true"> <key column="course_id"></key> <many-to-many class="org.fool.model.Student" column="student_id"> </many-to-many> </set> </class> </hibernate-mapping>
4 Test it
package org.fool.test; import java.util.HashSet; import java.util.Set; import org.fool.model.Course; import org.fool.model.Student; import org.fool.util.HibernateUtil; import org.hibernate.Session; import org.hibernate.Transaction; public class HibernateTest { public static void main(String[] args) throws Exception { // insert(); // select(); // update(); // delete(); } public static void insert() { Session session = HibernateUtil.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); Student student = new Student(); student.setName("lisi"); Course course = new Course(); course.setName("music"); student.setCourses(new HashSet<Course>()); course.setStudents(new HashSet<Student>()); student.getCourses().add(course); course.getStudents().add(student); session.save(student); tx.commit(); } catch (Exception ex) { ex.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } } public static void select() { Session session = HibernateUtil.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); Student student = (Student) session.get(Student.class, 1); Set<Course> courses = student.getCourses(); for (Course course : courses) { System.out.println(course.getName()); } tx.commit(); } catch (Exception ex) { ex.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } } public static void update() { Session session = HibernateUtil.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); Student student = (Student) session.get(Student.class, 1); Course course = (Course) session.get(Course.class, 1); student.setName("zhangsan"); course.setName("hibernate"); session.update(student); tx.commit(); } catch (Exception ex) { ex.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } } public static void delete() { Session session = HibernateUtil.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); Student student = (Student) session.get(Student.class, 1); Course course = (Course) session.get(Course.class, 1); student.getCourses().remove(course); tx.commit(); } catch (Exception ex) { ex.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } } }
5.Result
6.小结
由于多对多的关系不论在哪一方来维护都非常的麻烦,而且很多时候,关联表中需要加入其它的属性,所以一般情况都是把多对多拆分为两个一对多。
最佳实践:一般不使用双向关联,特别不建议使用一的这一方的关联,因为从一的这一方取关联对象很有可能会涉及到分页操作,所以基本不会使用,在设计的时候不是特殊情况不要使用双向关联。
相关推荐
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关联是常见的关系映射类型,尤其在处理数据库中的复杂关系时显得尤为重要。本主题将深入探讨使用Hibernate进行多对多双向关联的实现,既可以通过注解...
7.4.1. 一对多(one to many) / 多对一(many to one) 7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
在Hibernate的XML映射文件中,我们可以使用`<one-to-many>`和`<many-to-one>`元素来定义关联。 1. **在父类的映射文件中**,使用`<one-to-many>`元素声明一对多关联,并通过`class`属性指定子类的全限定类名。 ```...
7.4.1. 一对多(one to many) / 多对一(many to one) 7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many ...
7.4.1. 一对多(one to many) / 多对一(many to one) 7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...
在Java的持久化框架Hibernate中,多对多(Many-to-Many)关联是一种常见的关系映射类型,它用于表示两个实体之间可以有多个对应的关系。本篇将详细讲解如何使用Hibernate实现多对多单向关联,包括注解(Annotation)...
一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...
8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在集合中出现的依赖对象 ...
8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...
一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖对象 ...
<many-to-one name="clazz" column="class_id" class="com.example.Class" cascade="all"/> </hibernate-mapping> ``` 而在`class.hbm.xml`中,我们只需要定义`Class`实体的基本信息: ```xml <hibernate-...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...