Hibernate学习之双向一对多映射(双向多对一映射)
© 版权声明:本文为博主原创文章,转载请注明出处
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
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.hibernate</groupId>
<artifactId>Hibernate-TwoWayOneToMany</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.7.Final</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
</dependencies>
</project>
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; @Entity
public 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; @Entity
public 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 Set<Student> students = new HashSet<Student>(); 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<Student> getStudents() {
return students;
} public void setStudents(Set<Student> students) {
this.students = students;
} }
5.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> <class name="org.hibernate.entity.Student" table="student">
<id name="sid" type="java.lang.Integer">
<column name="sid"/>
<generator class="native"/>
</id>
<property name="sname" type="java.lang.String">
<column name="sname"/>
</property>
<property name="sex" type="java.lang.String">
<column name="sex"/>
</property>
<!-- 配置多对一映射关系 -->
<many-to-one name="grade" column="gid" cascade="save-update" class="org.hibernate.entity.Grade"/>
</class> </hibernate-mapping>
6.Grade.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> <class name="org.hibernate.entity.Grade" table="grade">
<id name="gid" type="java.lang.Integer">
<column name="gid"/>
<generator class="native"/>
</id>
<property name="gname" type="java.lang.String">
<column name="gname"/>
</property>
<property name="gdesc" type="java.lang.String">
<column name="gdesc"/>
</property>
<!-- 配置一对多映射关系 -->
<set name="students" cascade="all" lazy="true" inverse="true">
<key column="gid"/>
<one-to-many class="org.hibernate.entity.Student"/>
</set>
</class> </hibernate-mapping>
7.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> <!-- 配置SessionFactory -->
<session-factory>
<!-- 配置数据库连接信息 -->
<property name="connection.drvier_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">
jdbc:mysql:///hibernate?useSSL=true&characterEncoding=UTF-8
</property>
<property name="connection.user">root</property>
<property name="connection.password">***</property>
<!-- 配置hibernate常用配置 -->
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property><!-- 方言 -->
<property name="hbm2ddl.auto">update</property><!-- 是否自动创建表结构 -->
<property name="show_sql">true</property><!-- 是否展示SQL -->
<!-- 引入映射类 -->
<mapping class="org.hibernate.entity.Student"/>
<mapping class="org.hibernate.entity.Grade"/>
<!-- 引入映射文件 -->
<!-- <mapping resource="hbm/Student.hbm.xml"/>
<mapping resource="hbm/Grade.hbm.xml"/> -->
</session-factory> </hibernate-configuration>
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方法
Hibernate学习之双向一对多映射(双向多对一映射)的更多相关文章
- 【Mybatis高级映射】一对一映射、一对多映射、多对多映射
前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...
- Hibernate学习(四)———— 双向多对多映射关系
一.小疑问的解答 问题一:到这里,有很多学习者会感到困惑,因为他不知道使用hibernate是不是需要自己去创建表,还是hibernate全自动,如果需要自己创建表,那么主外键这种设置也是自己设置吗? ...
- hibernate笔记--单(双)向的多对多映射关系
在讲单向的多对多的映射关系的案例时,我们假设我们有两张表,一张角色表Role,一张权限表Function,我们知道一个角色或者说一个用户,可能有多个操作权限,而一种操作权限同时被多个用户所拥有,假如我 ...
- Hibernate中的一对多与多对一映射
1.需求 一个部门有多个员工; [一对多] 多个员工,属于一个部门 [多对一] 2.实体Bean设计 Dept: public class Dept { private int ...
- Hibernate学习4—关联关系一对多映射2
第四节:班级学生一对多映射实现(双向) 查询班级的时候能够获取所有的学生: 在上一节的基础之上:我们在Class端也保存学生的关系: com.cy.model.Class: public clas ...
- Hibernate学习4—关联关系一对多映射
一.班级学生一对多映射实现(单向) Class 1 * Student 一对多 在学生多的一方,配置一的对象: com.cy.model.Class: package com.cy.model; ...
- Hibernate学习之单向一对多映射
© 版权声明:本文为博主原创文章,转载请注明出处 说明:该实例是通过映射文件和注解两种方式实现的.可根据自己的需要选择合适的方式 实例: 1.项目结构 2.pom.xml <project xm ...
- HIbernate学习笔记4 之 延迟加载和 关联映射
一.延迟加载 * 在使用hibernate一些方法的查询数据的时候,返回的只是一个空对象(除id外属性都为NULL),并没有真正的查询数据库,而是在使用这个对象时才会触发查询数据库,并将这些数据注入到 ...
- Hibernate学习---第八节:继承关系的映射配置
1.单表继承 (1).实体类,代码如下: package learn.hibernate.bean; import java.util.Date; /** * 持久化类设计 * 注意: * 持久化类通 ...
- 【hibernate学习杂记】维护关系的一方和不维护关系的一方的区别与联系
双向多对一/一对多例子 维护关系一方为User:多方 不维护关系的一方为Group:一方 以下是多方代码: package Hibernate_demo1.Demo8.Entity.OneToMany ...
随机推荐
- Python_Tips[3] -> sort/sorted 排序函数
排序函数 / Sort Function list自带的sort函数可以实现对列表的排列功能,具有同样功能的还有sorted函数. 基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址 ...
- UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)
[题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树 ...
- Android Developer -- Bluetooth篇 开发实例之三 管理连接
Managing a Connection When you have successfully connected two (or more) devices, each one will have ...
- MySQL Cluster导入数据表时报错:Got error 708 'No more attribute metadata records (increase MaxNoOfAttributes)' from NDBCLUSTER
准备把以前的非集群版MySQL数据导入到MySQL Cluster中,出现 'No more attribute metadata records (increase MaxNoOfAttribute ...
- Android如何缓存你的BITMAP对象
在app中通常最占内存.占流量的元素就是图片了,图片往往又无处不在,特别是伴随着list,GridView或者ViewPager出现,这些图片随着你的滑动操作,时而出现在你的屏幕中,时而消失在屏幕之外 ...
- 【java】在controller层使用的检查单一字段不能为null和检查属性中某些字段不能为null的工具
========================================================================================= 代码参考地址:Git ...
- UVa1347 Tour
/*----UVa1347 ---首相两边方向走不方便,可以看做:两个人同时从最左边出发,沿着两条不同路径走到终点,除了起点和中点外 其他点恰好被走过一遍 ---用dp[i][j]表示1-max(i, ...
- Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details.
在android上发布遇到 androidSDK无法找到的问题 http://www.jianshu.com/p/fe4c334ee9fe
- Linux修改SSH端口
为什么要修改默认22端口 最近公司ssh全部换掉了默认的22端口,主要是为了防止被黑客大规模的扫描. 修改步骤 如果有需要请关闭防火墙(防止改错端口无法登陆) 修改sshd_config vim /e ...
- 配置多层NAT和端口映射实现外网访问内网
配置多层NAT和端口映射实现外网访问内网 背景和原理 通过配置NAT可以实现内网中不能直接访问外网的主机通过NAT代理访问内网,配置方法这里不再赘述(前文有介绍).本文以两层的NAT代理做模拟,通过端 ...