一、单向多对一关联关系

  一)、使用LocalSessionFactoryBean类,即在applicationContext中配置的

  1. <!-- 配置SessionFactory 使用LocalSessionFactoryBean-->
  2. <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  3. <property name="dataSource" ref="dataSource"></property>
  4. <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
  5. <property name="mappingLocations" >
  6. <list>
  7. <value>classpath:com/zcd/hibernate/manyToOne/*.hbm.xml</value>
  8. <value>classpath:com/zcd/hibernate/manyToOneBoth/*.hbm.xml</value>
  9. <value>classpath:com/zcd/hibernate/oneToMany/*.hbm.xml</value>
  10. <value>classpath:com/zcd/hibernate/oneToOneForeign/*.hbm.xml</value>
  11. <value>classpath:com/zcd/hibernate/oneToOnePrimary/*.hbm.xml</value>
  12. </list>
  13. </property>
  14. </bean>

    ①、以上配置的这个SessionFactory 类的对象的getCurrentSession()方法获取的Session 对象

      先保存一端再保存多端:正常

      先保存多端再保存一端:异常

    ②、但是如果使用这个对象的openSession() 方法

      先保存一端再保存多端:正常

      先保存多端再保存一端:没有异常,但不能保存外键列

====================================================================

  二)、如果通过以下方式获取的SessionFactory ,我看了一下底层代码,如果没错的话这个SessionFactory 指的是SessionFactoryImpl 这个类。

  1. private SessionFactory sessionFactory;
  2. private Session session;
  3. private Transaction transaction;
  4.  
  5. @Before
  6. public void init()
  7. {
  8. //创建一个Configuration对象:对应于hibernate的配置信息和对象关系映射
  9. Configuration configuration = new Configuration().configure();
  10.  
  11. //创建一个ServiceRegistry对象,所有的hibernate配置和服务都要注册到这个对象中才有效
  12. ServiceRegistry serviceRegistry =
  13. new ServiceRegistryBuilder().applySettings(configuration.getProperties())
  14. .buildServiceRegistry();
  15.  
  16. //创建SessionFactory对象
  17. sessionFactory = configuration.buildSessionFactory(serviceRegistry);
  18.  
  19. //创建Session
  20. session = sessionFactory.openSession();
  21. // session = sessionFactory.getCurrentSession();
  22.  
  23. //开启事务
  24. transaction = session.beginTransaction();
  25. System.out.println(transaction);
  26. }

    ①、这个SessionFactory 类的对象的getCurrentSession()方法获取的Session对象

      先保存一端再保存多端:异常

      先保存多端再保存一端:异常

    ②、但是如果通过openSession()方法获取的Session对象,

      先保存一端再保存多端:正常

      先保存多端再保存一端:正常, 但是会多出UPDATE语句。

=======================================================================

总结:在保存单向多对一关联关系的对象的时候,最好是先保存一端,再保存多端,这样既可以提高数据库的性能,又可以减少异常的发生。

二、一对一关联关系,基于主键映射。

跟上面的一样两种方式获取不同的SessionFactory 的实现类的实例

  一)、LocalSessionFactoryBean 实现类

    ①、getCurrentSession()方法获取的Session 对象。

      举例子:有Boss 和Company 两个类。Boss类对应的表主键类又做为外键列。

      先保存有外键的一端。

  1. //设定关联关系
  2. company.setBoss(boss);
  3. boss.setCompany(company);
  4.  
  5. //先保存有外键的一端
  6. oneToOnePrimaryService.saveBoss(boss);
  7. oneToOnePrimaryService.saveCompany(company);

      此时会重复保存两次 Company 对象,个人猜测:可能是因为boss中已经持有了company 的引用,所以在保存boss 的时候也保存了company对象,接着又保存了一次company,所以才会出现保存两次的情况。但是在保存boss对象的时候也是先保存了boss引用的company对象。

      先保存没有外键的一端

  1. //设定关联关系
  2. company.setBoss(boss);
  3. boss.setCompany(company);
  4.  
  5. //先保存没有外键的一端
  6. oneToOnePrimaryService.saveCompany(company);
  7. oneToOnePrimaryService.saveBoss(boss);

此时先保存company,在保存boss,属于正常,而且company 也不会重复保存。

===================================================================

    ②、如果是使用openSession()方法获取的session对象

      先保存有外键的一端:虽然没有发生异常,但是不能正常保存

  

      先保存没有外键的一端:虽然没有发生异常,但是不能正常保存

  二)、SessionFactoryImpl 实现类获取的

    ①、使用getCurrentSession() 方法获取session对象。 

      先保存有外键的一端: 异常

      先保存没有外键的一端:异常

    ②、使用openSession()方法获取Session对象。

      先保存有外键的一端: 正常保存

      先保存没有外键的一端:正常保存

      而且基于主键映射的使用openSession()方法获取的 Session 保存对象,不论先保存哪一端都不会发送update 语句

---------------------------------------------------------------------------------------------------------------------

总结:所以以后一对一映射最好保存没有外键的一端。

三、一对一关联关系基于外键映射

  跟上面一样的方式获取不同的SessionFactory 的实现类的实例

  一)、LocalSessionFactoryBean 类

    ①、使用getSessionFactory()方法

      先保存有外键的一端:  异常

      先保存没有外键的一端: 正常保存

    ②、使用openSession()方法

      先保存有外键的一端: 不能正常保存,有外键的一端不能正常保存外键列,因为没有发送update语句。

      先保存没有外键的一端: 正常保存,没有update语句

  二)、SessionFactoryImpl 类

    ①、使用getSessionFactory()方法

      先保存有外键的一端:发生异常

      先保存没有外键的一端:发生异常

    ②、使用openSession()方法

      先保存有外键的一端:正常保存,但会发送update语句

      先保存没有外键的一端:正常保存,而且不会发送update语句。

---------------------------------------------------------------------------------------------------------------------------------

总结:在使用一对一关联关系时,保存对象不管使用哪个SessionFactory的实现类的哪个方法获取Session,在保存对象时最好先保存没有外键列的一端。

四、双向多对一关联关系

  一)、LocalSessionFactoryBean 类

    ①、

    ②、

  二)、SessionFactoryImpl 类

    ①、

    ②、

五、双向多对多关联关系

  一)、LocalSessionFactoryBean 类

    ①、

    ②、

  二)、SessionFactoryImpl 类

    ①、

    ②、

关于SessionFactory的不同实现类分别通过getCurrentSession()方法 和 openSession() 方法获取的Session对象在保存对象时的一些区别的更多相关文章

  1. 简述JavaScript对象、数组对象与类数组对象

    问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...

  2. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  3. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  4. Android 通过 Intent 传递类对象或list对象

    (转:http://www.cnblogs.com/shaocm/archive/2013/01/08/2851248.html) Android中Intent传递类对象提供了两种方式一种是 通过实现 ...

  5. JOptionPane类提示框的一些常用的方法

    JOptionPane类提示框的一些常用的方法 XMLOracleSwing 最近在做swing程序中遇到使用消息提示框的,JOptionPane类其中封装了很多的方法. 很方便的,于是就简单的整理了 ...

  6. Javascript定义类(class)的三种方法

    将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...

  7. zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法

    转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法: ze ...

  8. 转载:java 中对类中的属性使用set/get方法的意义和用法

    经常看到有朋友提到类似:对类中的属性使用set/get方法的作用?理论的回答当然是封闭性之类的,但是这样对我们有什么作用呢?为什么要这样设计?我直接使用属性名来访问不是更直接,代码更简洁明了吗?下面我 ...

  9. 监听器和普通类获取springContext和context,从而获取springbean和application范围的对象

    1.定义一个监听器[MyContextListener],此类里最主要获取springContext和context package my.request; import javax.servlet. ...

随机推荐

  1. 获取各站点的ID

    using (var serverManager = new ServerManager()) { foreach(var site in serverManager.Sites) { Console ...

  2. lua "诡异"的return用法

    https://yq.aliyun.com/articles/11387 lua "诡异"的return用法   德哥 2016-03-29 15:38:42 浏览5690 评论0 ...

  3. Beyond Compare 4试用期已过

    Beyond Compare 很好用,但是只有一段时间的试用时间,当试用期过了之后就提示不能试用了 怎么办呢? 我在网上找到了两个方法: 1.直接用注册码(来自:https://blog.csdn.n ...

  4. git提交代码报错 trailing whitespace的解决方法

    1. git提交代码报错 trailing whitespace 禁止执行pre-commit脚本 进入到项目目录中 chmod a-x .git/hooks/pre-commit 2.git提交代码 ...

  5. java实现截取6个汉字字母数字

    项目中使用到需要截取6个字(12个字母或数字),解决方法如下: /** * * @方法名称:getWordCount * @内容摘要: <截取输入字符串 大于6个后显示...> * @pa ...

  6. JavaScript对象 继承

    JavaScript继承主要依靠原型链实现. 原型链 利用原型让一个引用类型继承另一个引用类型水位属性和方法. 每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指 ...

  7. linux修改文件权限命令(chmod)

    chmod命令是用于改变文件或目录的访问权限.用户用它控制文件或目录的访问权限. 该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1.文字设定法 chmod ...

  8. Paxos、ZAB、RAFT协议

    这三个都是分布式一致性协议,ZAB基于Paxos修改后用于ZOOKEEPER协议,RAFT协议出现在ZAB协议之后,与ZAB差不多,也有很大区别. 1. Paxos 分布式节点分为3种角色, Prop ...

  9. PAT 1025 PAT Ranking

    #include <cstdio> #include <cstdlib> #include <vector> #include <cstring> #i ...

  10. 阿里云服务器Linux常用命令

    系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...