Hibernate(或其它ORM)里的inverse用法详解,内容摘自Java web轻量级开发面试教程
本文来是从 java web轻量级开发面试教程从摘录的。
Inverse的英文含义是反转,在Hibernate中用来决定是由哪方来维护两个业务实体类之间的关联关系,具体而言,就是由哪方去设置这个被外键约束的字段值。
它的默认值是false,也就是说,本端(比如inverse=false写在学生端,那么本端是学生,另外一方是课程)不“反转控制权”,这句别扭的话的另外一种说法是,本端维护关联关系。如果两边都不写,那么两端都维护。这样会造成问题,即新时因为两端都控制关系,因此可能会导致重复更新。
注意,inverse仅仅是指定由谁来设置外键值,而不是用来设置级联操作,级联操作的方式由cascade来负责,很多人会混淆它们的含义和用法。
这个例子所用到的数据表是Person表和Card表,其中Person表里包含ID、Name和Phone字段,而Card表里包含了CardID、PersonID、Bank和balance四个字段。
在hibernate.cfg.xml文件里,通过mapping resource来指定对应的映射文件,其中关键的代码如下:
1 <!-- 添加实体类的映射文件-->
2 <mapping resource="Model/Card.hbm.xml" />
3 <mapping resource="Model/Person.hbm.xml" />
在Person.hbm.xml里,用如下代码来指定人(一方)和卡(多方)的关系,其中在人这一端,inverse是true。
1 <set name="cards" cascade="save-update" inverse="true">
2 <key column="PersonID"/>
3 <one-to-many class="Card"/>
4 </set>
在HibernateMain.java里,通过如下关键代码插入了一个人的信息。
1 //创建一张卡
2 Card card1 = new Card();
3 card1.setCardID("Card123");
4 card1.setPersonID("Person123");
5 card1.setBank("Citi");
6 card1.setBalance(100f);
7 //初始化一个人
8 Person person = new Person();
9 person.setID("Person123");
10 person.setName("Peter");
11 person.setPhone("123456");
12 //在cards这个set里加入card1
13 Set<Card> cards = new HashSet<Card>();
14 cards.add(card1);
15 person.setCards(cards);
16 //保存人的信息
17 session.save(person);
18 session.flush();
运行后,在输出信息里能看到如下两条相关的插入语句:一条是插入Person信息,另一条是插入card信息。
1 Hibernate: insert into Person (Name, Phone, ID) values (?, ?, ?)
2 Hibernate: insert into Card (PersonID, Bank, Balance, Person, CardID) values (?, ?, ?, ?, ?)
当把person.hbm.xml里的inverse设置成false时,能看到相关的语句里会多出一句update语句。
1 Hibernate: insert into Person (Name, Phone, ID) values (?, ?, ?)
2 Hibernate: insert into Card (PersonID, Bank, Balance, Person, CardID) values (?, ?, ?, ?, ?)
3 Hibernate: update Card set PersonID=? where CardID=?
原因是,当设置inverse为true时,Person这一端反转外键控制权,也就是由Card这端来管理外键,而在代码里我们仅仅是插入了Person,没有插入Card,所以就没有更新两个外键(PersonID和CardID)的操作。相反,当inverse为false时,管理外键控制权是在Person端,那么当插入Person时,Hibernate就需要额外的一句update语句来管理外键了。
在一对多的例子里,inverse不论取什么值,对结果都没有影响,所以很容易让人忽视它的作用。
在一对多的例子里,一般是让多方来管理外键控制权,比如一个人有100张开,那么如果由Person方来管理的话,无形中可能会多出100个update操作,效率上就不大好了。
如果在一对多案例中,inverse只是影响效率的话,那么在多对多的例子中,inverse的设置就可能影响到数据。
我们再来看个多对多的学生选课案例,其中一个学生可以选多门课,而一门课里可以有多个学生。在Student.hbm.xml里,描述多对多关系的语句里可加上inverse=“true”的语句。
1 <set name="courses" table="students_courses" inverse= "true" cascade="save-update">
2 <key column="student_id"></key>
3 <many-to-many class="Model.Course" column="course_id"></many-to-many>
4 </set>
在Course.hbm.xml里,不加任何关于inverse的语句,也就是说,在Student端反转外键控制权,把控制权交到Course端。
在HibernateMain这个类里,通过如下代码让s1学生选修计算机课程。
1 //设置一个学生,学号是1
2 Student s1 = new Student();
3 s1.setStudentID("1");
4 s1.setStudentName("Peter");
5 //设置多个课程
6 Course c1 = new Course();
7 c1.setCourseID("c1");
8 c1.setCourseName("Math");
9 Course c2 = new Course();
10 c2.setCourseID("c2");
11 c2.setCourseName("Java");
12 Course c3 = new Course();
13 c3.setCourseID("c3");
14 c3.setCourseName("C#");
15 //设置计算机课程这个Set
16 Set<Course> computerCourses = new HashSet<Course>();
17 computerCourses.add(c2);
18 computerCourses.add(c3);
19 //让s1这个学生选修计算机课程(也就是c2和c3课程)
20 s1.setCourses(computerCourses);
21 //保存s1
22 session.save(s1);
23 session.flush();
执行结果是,虽然能在Student和Course表里看到相关的学生和课程的记录,但在关键的描述学生选课关联表(students_courses)里,看不到任何关联记录。原因是已经通过设置inverse把外键管理权交给Course方了,这里仅仅是保存学生,并没有保存课程,所以没有插入外键的动作。如果要在students_courses表里插入外键关联,就需要在person.hbm.xml里设置inverse的值为false。
所以,在多对多关联里,设置错了inverse值会导致结果出错,请大家根据具体项目的情况适当设值。
Hibernate(或其它ORM)里的inverse用法详解,内容摘自Java web轻量级开发面试教程的更多相关文章
- Java web开发,在一个jsp里放太多java代码的后果,摘自 java web轻量级开发面试教程
现要做一个简单的登录页面,如果用户通过验证,会显示Welcome用户名的欢迎词,反之则返回登录页面让用户再次输入 这部分的完整代码是JSPDemo项目里的login.jsp,下面来分析一下关键代码. ...
- Linux编程里getopt_long_only函数用法详解
在程序中难免需要使用命令行选项,可以选择自己解析命令行选项,但是有现成的,何必再造轮子.下面介绍使用getopt_long_only和getopt_long(两者用法差不多)解析命令行选项. 程序中主 ...
- 【译】css动画里的steps()用法详解
原文地址:http://designmodo.com/steps-c... 原文作者:Joni Trythall 我想你在css 动画里使用steps()会和我一样有很多困惑.一开始我不清楚怎样使用它 ...
- Unity 3D光源-Spot Light聚光灯用法详解、模拟手电筒、台灯等线性教程
Unity4大光源之聚光灯 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...
- Linux Shell脚本入门--wget 命令用法详解
Linux Shell脚本入门--wget 命令用法详解 wget是在Linux下开发的开放源代码的软件,作者是Hrvoje Niksic,后来被移植到包括Windows在内的各个平台上.它有以下功能 ...
- netstat用法详解
netstat用法详解 知识,netstat用法详解 图片 netstat用法详解 内容,netstat用法详介绍,netstat用法详正文 netstat命令是一个监控TCP/IP网络的非常有用的工 ...
- BigDecimal的用法详解(保留两位小数,四舍五入,数字格式化,科学计数法转数字,数字里的逗号处理)
转自:https://blog.csdn.net/ochangwen/article/details/51531866 一.简介 Java在java.math包中提供的API类BigDecimal,用 ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- @RequestMapping 用法详解之地址映射
@RequestMapping 用法详解之地址映射 引言: 前段时间项目中用到了RESTful模式来开发程序,但是当用POST.PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没 ...
随机推荐
- JavaScript 经典之一 闭包
作为一个前端开发者,闭包是必须要攻克掉的障碍.据说好多面试者挂在闭包面试上.下面我就给大家讲一下我理解中的闭包.不说太多的废话,直接进入主题. 变量作用域 学习编程语言需要明白,变量的作用域.变量作用 ...
- JDBC之代码优化
上一次我们是先实现了JDBC对数据库的增删查改操作,然后在增加新信息过程中发现了新的问题,即当某一操作失败,为了维护数据库的一致性,我们需要回滚事务.在其中我们了解了事务的工作原理及相关代码的使用. ...
- CLR类型设计之泛型(二)
在上一篇文章中,介绍了什么是泛型,以及泛型和非泛型的区别,这篇文章主要讲一些泛型的高级用法,泛型方法,泛型接口和泛型委托,协变和逆变泛型类型参数和约束性,泛型的高级用法在平时的业务中用的不多,多用于封 ...
- Python使用虚拟环境
这里想象一下需求,写一个项目使用的一系列1.0版本的插件,现在要新写一个项目,需要用这些插件的2.0版本,该怎么办?都更新成2.0版本?这样之前的项目都没法维护了 这时我们需要一个虚拟环境,Pytho ...
- 实战项目——mysql主从架构的实现
一主一从 1.1 环境准备: centos系统服务器2台. 一台用户做Mysql主服务器, 一台用于做Mysql从服务器, 配置好yum源. 防火墙关闭. 各节点时钟服务同步. 各节点之间可以通过主机 ...
- mysql 查询各数据库的占用大小
select TABLE_SCHEMA, concat(truncate(sum(data_length)/1024/1024,2),' MB') as data_size, concat(trunc ...
- java oop详解
近日来重温了一下java oop的知识.加深了对面向对象的理解.尤其时继承方面.故写一篇博客.记录一下自己的想法和心得 1.面向对象主要分为三大点(封装,继承,多态) 封装的思想促进了类的形成.相比于 ...
- 关于laravel 用paginate()取值取不到的问题
前几天在写api的时候,出现了一个比较奇怪的问题,用paginate()方法取值取不到的问题,我奇怪的是,我用paginate()方法取值是直接复制粘贴之前自己写过的api中的代码的,怎么突然取不到了 ...
- Struts 2 入门
Struts 2 入门: 一:Struts 2执行流程: 1 客户端发送请求: 2这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤 ...
- 虚拟机安装 deepin Linux 注意事项
主要要注意下面几点: 一.虚拟机"客户机操作系统"类型 选择"Windows 7 x64" 选择"客户机操作系统"类型,这个选择十分重要,D ...