- 浏览: 2309062 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (314)
- JAVA基础知识 (54)
- Java-IO/FIle (16)
- Java-JDBC (4)
- JAVA-新增特性-注解 (3)
- Java-枚举 (2)
- Java-泛型 (1)
- Java-多线程 (15)
- Java-XML (4)
- Java-JMS(消息服务) (4)
- Java-JVM (0)
- Web Service服务 (7)
- Jsp (10)
- js (18)
- Struts框架 (11)
- Spring框架 (29)
- Hibernate框架 (28)
- Spring Boot框架 (2)
- ExtJS前端框架 (29)
- Jquery js库 (8)
- JUnit框架 (8)
- Selenium 测试 (1)
- NoSql---Redis (6)
- ORACLE数据库 (45)
- MySQL数据库 (4)
- tomcat (3)
- Nginx反向代理服务器 (4)
- web应用服务器通用知识 (3)
- 开发工具IDE (14)
- UML建模 (1)
- SVN CVS 版本管理 (6)
- git 分布式版本管理 (4)
- 报表设计 (5)
- 文件上传下载 (2)
- 数据算法 (1)
- 存储过程 (5)
- JSON 相关 (1)
- OGNL表达式 (3)
- Util工具包 (9)
- 设计模式 (15)
- linux 相关 (3)
- life think (3)
- 工作流管理框架 (1)
- 大数据-Hadoop (1)
最新评论
-
huih:
很不错的文章
SpringMVC+Hibernate+Spring 简单的一个整合实例 -
calm01:
学习了.
Spring <bean>标签属性 Autowire自动装配(转载) -
lizhenlzlz:
我的也是拦截不了service层
SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)(转载) -
josh_123:
讲的不错,很详细,如果quartz定时任务类采用不继承任何类的 ...
Spring,jdk定时任务的几种实现以及任务线程是串行还是并行执行(转载) -
human_coder:
你知道eclipse调试怎么可以回调吗?有时候总是调快了,不能 ...
Debug---Eclipse断点调试基础
通过Hibernate Inverse的设置来决定是由谁来维护表和表之间的关系。最近有朋友问我Hibernate关于多对多关于删除中间表数据的问题,关键是Inverse的设置,下面引用网友的一篇文章。
Inverse是Hibernate双向关系中的基本概念,当然对于多数实体,我们并不需要双向关联,更多的可能会选择单向关联,况且我们大多数人 一般采用一对多关系,而一对多双向关联的另一端:多对一的Inverse属性是不存在,其实它默认就是Inverse=false.从而防止了在一对多端 胡乱设置Inverse也不至于出错。但是Inverse设置不当确实会带来很大的性能影响,这点是我们必须关注的。
这篇文章已经详细分析了Hibernate Inverse设置不当带来的影响:http://www.Hibernate.org/155.html,看了这篇文章,还是很有必要再写下一些总结的:
1)Hibernate Inverse中提及的side其实是指一个类或者表的概念,双向关联其实是指双方都可以取得对方的应用。
2)维护关系这个名词还是稍显模糊或者晦涩。我们一般说A类或者A表(这里的表的是指多对多的连接表)有责任维护关系,其实这里的意思是说,我在应 用在更新,创建,删除(读就不用说了,双向引用正是为了方便读而出现)A类或者A表时,此时创建的SQL语句必须有责任保证关系的正确修改。
3)Inverse=false的side(side其实是指Inverse=false所位于的class元素)端有责任维护关系,而Inverse=true端无须维护这些关系。
4)我们说Hibernate Inverse设立不当会导致性能低下,其实是说Inverse设立不当,会产生多余重复的SQL语句甚至致使JDBC exception的throw。这是我们在建立实体类关系时必须需要关注的地方。一般来说,Inverse=true是推荐使用,双向关联中双方都设置 Inverse=false的话,必会导致双方都重复更新同一个关系。但是如果双方都设立Inverse=true的话,双方都不维护关系的更新,这也是 不行的,好在一对多中的一端:many-to-one默认是Inverse=false,避免了这种错误的产生。但是多对多就没有这个默认设置了,所以很 多人经常在多对多的两端都使用Inverse=true,结果导致连接表的数据根本没有记录,就是因为他们双分都没有责任维护关系。所以说,双向关联中最 好的设置是一端为Inverse=true,一端为Inverse=false。一般Inverse=false会放在多的一端,那么有人提问了, many-to-many两边都是多的,Inverse到底放在哪儿?其实Hibernate建立多对多关系也是将他们分离成两个一对多关系,中间连接一 个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分。
看下面的多对多的定义大家更会清楚”多对多“与“一对多”的关系:其中我们注意<many-to-many />标签的特点就知道,它是定义了一个多对多关系,而不是<one-to-many/>。
- <?xml version="1.0"?>
- <!DOCTYPE Hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
- "http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">
- <Hibernate-mapping package="org.Hibernate.auction">
- <class name="TestA" table="TestA"
- dynamic-update="true" dynamic-insert="true" >
- <id name="id" column="id" type="int" unsaved-value="any" >
- <generator class="assigned">
- </generator>
- </id>
- <property name="name" type="java.lang.String"
- update="true" insert="true" column="name" />
- <set name="testBs" table="TestA_TestB" Inverse="false" cascade="all">
- <key column="testA"/>
- <many-to-many column="testB" class="TestB" />
- </set>
- </class>
- <class name="TestB" table="TestB"
- dynamic-update="true" dynamic-insert="true" >
- <id name="id" column="id" type="int" unsaved-value="any" >
- <generator class="assigned">
- </generator>
- </id>
- <property name="name" type="java.lang.String" update="true"
- insert="true" column="name" />
- <set name="testAs" table="TestA_TestB" Inverse="true" cascade="all">
- <key column="testB"/>
- <many-to-many column="testA" class="TestA" />
- </set>
- </class>
- </Hibernate-mapping>
在对多对中,因为一端维护关系另一端不维护关系的原因,我们必须注意避免在应用中用不维护关系的类建立关系,因为这样建立的关系是不会在数据库中存储的。基于上面的映射文件代码给出一个例子:
- package org.Hibernate.auction;
- import java.util.*;
- /**
- * @author Administrator
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
- */
- public class TestA {
- int id;
- String name;
- Set testBs=new HashSet();
- public TestA(){
- }
- public TestA(int id){
- setId(id);
- }
- 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 getTestBs(){
- return testBs;
- }
- public void setTestBs(Set s){
- testBs=s;
- }
- public void addTestB(TestB tb){
- testBs.add(tb);
- }public static void main(String[] args) {
- }
- }
- public class TestB {
- int id;
- String name;
- Set testAs=new HashSet();
- public TestB(){
- }
- public TestB(int id){
- setId(id);
- }
- 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 getTestAs(){
- return testAs;
- }
- public void setTestAs(Set s){
- testAs=s;
- }
- public void addTestA(TestA ta){
- testAs.add(ta);
- }
- public static void main(String[] args) {
- }
- }
测试代码:
- public void doTest() throws Exception{
- TestA a1=new TestA(1);
- TestA a2=new TestA(2);
- TestA a3=new TestA(3);
- TestB b1=new TestB(1);
- TestB b2=new TestB(2);
- TestB b3=new TestB(3);
- a1.addTestB(b1);
- a1.addTestB(b2);
- a1.addTestB(b3);
- b2.addTestA(a1);
- b2.addTestA(a2);
- Session s = factory.openSession();
- s = factory.openSession();
- Session session = factory.openSession();
- session.save(a1);
- session.flush();
- session.close();
- }
测试后连接表的数据为:
testa testb
1 1
1 2
1 3
根据Inverse规则,对这些代码:b2.addTestA(a1); b2.addTestA(a2); 建立的关系,数据库并没有存储下来,因为TestB没有责任维护这些关系,所以产生的sql语句自然不会有针对Testa_testB表的操作了。假设应 用中真的需要这些方法,那么我们可以修改TestB的方法,让他们注意在维护端类中执行相应的操作以使得关系能够在数据库中保存下来,更改TestB如 下:
- /*
- * Created on 2004-7-25
- *
- * To change the template for this generated file go to
- * Window>Preferences>Java>Code Generation>Code and Comments
- */
- package org.Hibernate.auction;
- import java.util.*;
- /**
- * @author Administrator
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
- */
- public class TestB {
- int id;
- String name;
- Set testAs=new HashSet();
- public TestB(){
- }
- public TestB(int id){
- setId(id);
- }
- 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 getTestAs(){
- return testAs;
- }
- public void setTestAs(Set s){
- testAs=s;
- }
- public void addTestA(TestA ta){
- testAs.add(ta);
- ta.addTestB(this);
- }
- public static void main(String[] args) {
- }
- }
那么测试执行后连接表的数据为:
testa testb
1 2
1 3
1 1
2 2
测试通过。
发表评论
-
教你使用Hibernate的QBC查询(转载)
2015-12-18 17:19 4222转载自:http://developer.51cto.com ... -
hibernatesynchronizer3开发工具的使用方法
2014-11-24 14:35 25911. hibernatesynchronizer3可以帮助 ... -
Hibernate锁机制(悲观锁,乐观锁)
2014-09-24 17:16 2095锁(locking) 业务逻辑的实现过程中,往往需要保证 ... -
六种方式实现hibernate查询,及IDE推荐 (转载)
2014-07-16 18:13 1254hibernate查询的6种方法。分别是HQL查询,对象 ... -
SpringMVC+Hibernate+Spring 简单的一个整合实例
2014-07-04 16:14 87781SpringMVC又一个漂亮的web框架,他与Struts2 ... -
Struts2、hibernate和spring下载,整合所需jar包
2014-07-04 16:00 4459ssh三个框架各自所有版本下载地址如下 Struts f ... -
Hibernate Criteria的 Criterion,Projection,Restrictions等条件设置
2014-04-01 16:46 38023在查询方法设计上可以灵活的根据Criteria的特点来方便 ... -
Hibernate的Example示例查询
2013-07-29 17:32 4016org.hibernate.criterion.Ex ... -
Spring与Hibernate集成中的session问题
2013-04-15 15:53 31611.通过getSession()方法 ... -
剖析Hibernate主键生成几种常用方式
2012-12-05 20:01 13221.assigned: 主键由外部程序负责生成,无需H ... -
Hibernate中session.getconnection()的替代方法
2012-08-27 16:39 51752010-04-15 10:21 Hibernate ... -
Hql总结 查询结果动态组装成List(map),List(bean),List(list),List(set)等格式(转)
2012-08-17 15:51 73301.//查询整个对象String hql="from ... -
sql和hql中join语句区别,以及hibernate中内连接,迫切内连接,左外连接,迫切左外连接,右外连接的区别(合集)
2012-07-24 17:39 3213第一:sql和hql中join语 ... -
Hibernate_HQL--实体、属性查询,参数绑定,引用查询(随时温习一遍)
2012-07-05 17:52 15928是Hibernate官方推荐的查询模式,比Criteria功能 ... -
hibernate里createSQLQuery的addEntity()和setResultTransformer()方法
2012-06-21 10:55 565551. 使用SQLQuery对原生SQL查询执行的控制是通过S ... -
hibernate的session.connection被session.dowork()替代
2012-06-14 10:22 4089Hibernate3.3.2版本中getSessi ... -
Hibernate继承映射多态的详解
2012-06-05 17:36 1956在面向对象的程序领域中,类与类之间是有继承关系的,例如Java ... -
hibernateTemplate session关闭
2012-04-18 14:53 37761.虽然继承了HibernateDaoSupport这个类,但 ... -
No Hibernate Session bound to thread, and configuration does not allow creation
2012-04-18 10:57 2180用SessionFactory.getCurrentSessi ... -
Hibernate的generator属性之意义(转)
2012-04-01 11:06 1334Hibernate的Generator属性有7种class,本 ...
相关推荐
总结来说,理解并合理运用Hibernate中的`Inverse`属性对于优化数据操作、提高代码可读性和维护性具有重要意义。通过精确控制关联的维护责任,我们可以更好地管理对象关系,实现高效且一致的数据库操作。
在探讨Hibernate的`inverse`属性之前,我们先要理解Hibernate中的对象关系映射(ORM)以及持久化机制。Hibernate是一个流行的Java ORM框架,它允许开发者将数据库操作转换为面向对象的编程模型,使得数据操作更加...
- **多对多**:例如,一个`Student`和多个`Course`课程的关系,`inverse`属性通常放在独立的关系表中,并且只能在一方设置为`true`,另一方为`false`,以确保关系的正确维护。 #### 三、Cascade 属性详解 `cascade...
综上所述,理解并正确使用Hibernate中的`inverse`属性对于优化JavaEE应用的数据库操作和提高代码质量具有重要意义。通过深入掌握这一特性,开发者能够更好地管理对象之间的关联,提升应用的性能和稳定性。
在实际应用中,需要根据业务需求谨慎选择 `cascade` 和 `inverse` 的值,以确保数据的正确性和效率。 总之,`cascade` 和 `inverse` 是 Hibernate 中用来优化对象关系管理的两个关键特性,它们可以帮助开发者更有效...
### Hibernate常用注解详解 #### 一、JPA与Hibernate注解基础 JPA(Java Persistence API)是一种标准规范,用于实现对象关系映射(ORM),允许...理解和熟练掌握这些注解对于使用Hibernate进行持久化操作至关重要。
在开发中,理解并正确使用`inverse`属性对IDEA、Eclipse等开发工具的实体类生成和数据库同步功能至关重要。这些工具通常会根据`inverse`属性生成相应的SQL语句,因此理解这一特性有助于避免由工具生成的代码产生...
正确设置`inverse`可以确保Hibernate在处理关联关系时的行为符合预期。 #### 一对一与多对多实体映射 Hibernate支持一对一和多对多关系的映射,分别通过`@OneToOne`和`@ManyToMany`注解实现。这些映射策略使得复杂...
根据提供的文件信息,我们可以深入探讨Hibernate框架中的几个关键概念,特别是`fetch`, `lazy`, `cascade`, 和 `inverse`关键字的使用与理解。这四个概念在处理对象关系映射(ORM)时非常重要,尤其是在Java环境下...
源码分析有助于理解Hibernate的工作原理,而工具可能是简化配置或调试的辅助手段。 在文件名“bagMapping”中,我们可能假设这是一个示例或教程,包含有关如何设置和使用bag映射的配置文件、Java实体类和可能的测试...
通过阅读和实践这些代码,你可以更深入地理解Hibernate的关联映射,掌握cascade和inverse的实际应用技巧。 总之,理解并熟练运用Hibernate的关联映射、cascade和inverse是提升Java持久化编程能力的关键步骤。它们...
此外,还讨论了unsaved-value、Inverse和Cascade等概念,以及延迟加载机制,这些都是理解Hibernate数据访问模式的关键。 #### 事务管理与锁机制 事务管理是任何数据库操作中不可或缺的一部分,文档不仅阐述了基于...
理解并正确使用Hibernate的`cascade`和`inverse`属性对于优化数据操作和避免数据一致性问题至关重要。在实际开发中,应根据业务逻辑和数据模型谨慎设定这些属性,以确保数据操作的正确性和高效性。
2. **调试考虑:**在调试时,如果使用了延迟加载,要注意查看代理对象的实际类型,以确保正确理解其行为。 3. **性能考量:**虽然延迟加载可以减少初始加载时间,但过多的延迟加载也可能导致更多的数据库往返,因此...