© 版权声明:本文为博主原创文章,转载请注明出处
1.双向映射与单向映射
- 一对多单向映射:由一方(教室)维护映射关系,可以通过教室查询该教室下的学生信息,但是不能通过学生查询该学生所在教室信息;
删除教室时可以级联删除该教室下的所有学生信息。
- 多对一单向映射:由多方(学生)维护映射关系,可以通过学生查询该学生所在的教室信息,但是不能通过教室查询该教室下的所有学生信息;
并且删除教室的时候不能级联删除该教室下的所有学生信息。
- 一对多(多对一)双向映射:即在一方配置一对多的单向映射,在多方配置多对一的单向映射,因此默认双方都会对映射关系进行维护,所以可通过mappedBy(注解方式)
或inverse(xml方式)来指定多方不参与映射关系维护。双向映射既可以通过学生查询学生所在教室的信息,也可以通过教室查询该教室下的
所有学生信息;并且删除教室的时候可以级联删除该教室下的所有学生信息。故实际开发中多实用双向映射。
2.mappedBy和inverse
mappedBy:注解方式下使用,是在@OneToOne、@OneToMany、@ManyToMany上才有的属性,ManyToOne不存在该属性;在一的一方配置mappedBy将维护权
交由多的一方(因为外键在多的一方,所以多的一方维护起来更为方便);当使用mappedBy时不能再使用@JoinColumn
inverse:xml方式下使用,inverse="false"表示由自身维护映射关系,因此在一方将其设置为true,将维护权交给多的一方
3.@JoinColumn:此注解的作用是指定外键,避免生成第三种关系维护表
4.fetch=FetchType.*:数据加载方式
fetch=FetchType.EAGER:积极加载,加载数据时,将与该数据关联的数据也加载到内存中;一般在多方使用,因为关联的一方数据较少
fetch=FetchType.LAZY:延迟加载,加载数据时,不加载关联数据,当使用到关联数据时再从数据库中查询;一般在一方使用,因为关联的多方数据较多
实例:
1.项目结构
2.pom.xml
4.0.0 org.hibernate Hibernate-TwoWayOneToMany 0.0.1-SNAPSHOT jar UTF-8 junit junit 4.12 test org.hibernate hibernate-core 5.1.7.Final mysql mysql-connector-java 5.1.42
3.Student.java
package org.hibernate.entity;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import org.hibernate.annotations.Cascade;import org.hibernate.annotations.CascadeType;import org.hibernate.annotations.GenericGenerator;@Entitypublic class Student { @Id @GeneratedValue(generator="sid") @GenericGenerator(name="sid", strategy="native") private int sid;// 学号 @Column(length=100) private String sname;// 姓名 @Column(length=2) private String sex;// 性别 @ManyToOne(fetch=FetchType.EAGER) @Cascade(value=CascadeType.SAVE_UPDATE) @JoinColumn(name="gid") private Grade grade; public Student() { } public Student(String sname, String sex) { this.sname = sname; this.sex = sex; } public Student(String sname, String sex, Grade grade) { this.sname = sname; this.sex = sex; this.grade = grade; } 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; } }
4.Grade.java
package org.hibernate.entity;import java.util.HashSet;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToMany;import org.hibernate.annotations.GenericGenerator;@Entitypublic class Grade { @Id @GeneratedValue(generator="gid") @GenericGenerator(name="gid", strategy="native") private int gid;// 班号 @Column(length=100) private String gname;// 班名 private String gdesc;// 班级描述 //mappedBy表示grade表不再参与关系维护,将主控方交给学生类;配置了mappedBy就不能再@JoinColumn @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="grade") private Setstudents = new HashSet (); public Grade() { } public Grade(String gname, String gdesc) { this.gname = gname; this.gdesc = gdesc; } public int getGid() { return gid; } public void setGid(int gid) { this.gid = gid; } public String getGname() { return gname; } public void setGname(String gname) { this.gname = gname; } public String getGdesc() { return gdesc; } public void setGdesc(String gdesc) { this.gdesc = gdesc; } public Set getStudents() { return students; } public void setStudents(Set students) { this.students = students; } }
5.Student.hbm.xml
6.Grade.hbm.xml
7.hibernate.cfg.xml
com.mysql.jdbc.Driver jdbc:mysql:///hibernate?useSSL=true&characterEncoding=UTF-8 root *** org.hibernate.dialect.MySQL5InnoDBDialect update true
8.TestTwoWayOneToMany.java
package org.hibernate.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.entity.Grade;import org.hibernate.entity.Student;import org.junit.After;import org.junit.Before;import org.junit.Test;public class TestTwoWayOneToMany { private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before public void before() { // 创建SessionFactory对象 sessionFactory = new Configuration().configure().buildSessionFactory(); // 获取Session对象 session = sessionFactory.openSession(); // 开启事务 transaction = session.beginTransaction(); } @After public void after() { // 提交事务 transaction.commit(); // 关闭Session session.close(); // 关闭SessionFactory sessionFactory.close(); } @Test public void testAdd() { Grade grade = new Grade("Java一班", "Java应用开发一班"); Student student1 = new Student("张三", "男", grade); Student student2 = new Student("李四", "女", grade); session.save(student1); session.save(student2); session.save(grade); } @Test public void testQuery() { Grade grade = session.get(Grade.class, 1); System.out.println(grade.getGname() + " - " + grade.getGdesc()); for (Student student: grade.getStudents()) { System.out.println(student.getSname() + " - " + student.getSex()); } Student student = session.get(Student.class, 1); System.out.println(student.getSname() + " - " + student.getSex() + " - " + student.getGrade().getGname() + student.getGrade().getGdesc()); } @Test public void testUpdate() { Grade grade = new Grade("Java二班", "Java应用开发二班"); Student student = session.get(Student.class, 2); student.setGrade(grade); session.update(student); } @Test public void testDelete() { Grade grade = session.get(Grade.class, 2); session.delete(grade); Student student = session.get(Student.class, 1); session.delete(student); } }
9.效果预览
9.1 执行testAdd方法
9.2 执行testQuery方法
9.3 执行testUpdate方法
9.4 执行testDelete方法