博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于SessionFactory的不同实现类分别通过getCurrentSession()方法 和 openSession() 方法获取的Session对象在保存对象时的一些区别...
阅读量:4678 次
发布时间:2019-06-09

本文共 4522 字,大约阅读时间需要 15 分钟。

一、单向多对一关联关系

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

classpath:com/zcd/hibernate/manyToOne/*.hbm.xml
classpath:com/zcd/hibernate/manyToOneBoth/*.hbm.xml
classpath:com/zcd/hibernate/oneToMany/*.hbm.xml
classpath:com/zcd/hibernate/oneToOneForeign/*.hbm.xml
classpath:com/zcd/hibernate/oneToOnePrimary/*.hbm.xml

 

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

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

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

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

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

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

 

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

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

private SessionFactory sessionFactory;    private Session session;    private Transaction transaction;        @Before    public void init()    {        //创建一个Configuration对象:对应于hibernate的配置信息和对象关系映射        Configuration configuration = new Configuration().configure();                //创建一个ServiceRegistry对象,所有的hibernate配置和服务都要注册到这个对象中才有效        ServiceRegistry serviceRegistry =                 new ServiceRegistryBuilder().applySettings(configuration.getProperties())                .buildServiceRegistry();                //创建SessionFactory对象        sessionFactory = configuration.buildSessionFactory(serviceRegistry);                //创建Session        session = sessionFactory.openSession();//        session = sessionFactory.getCurrentSession();                //开启事务        transaction = session.beginTransaction();        System.out.println(transaction);    }

 

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

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

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

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

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

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

 

 

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

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

 

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

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

  一)、LocalSessionFactoryBean 实现类

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

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

      先保存有外键的一端。

//设定关联关系        company.setBoss(boss);        boss.setCompany(company);                //先保存有外键的一端        oneToOnePrimaryService.saveBoss(boss);        oneToOnePrimaryService.saveCompany(company);

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

      先保存没有外键的一端

//设定关联关系        company.setBoss(boss);        boss.setCompany(company);                //先保存没有外键的一端        oneToOnePrimaryService.saveCompany(company);        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 类

    ①、

    ②、

转载于:https://www.cnblogs.com/GooPolaris/p/7919628.html

你可能感兴趣的文章
使用 httpkit 来替代 jetty
查看>>
594. Longest Harmonious Subsequence
查看>>
ThinkPHP导入Excel文件(使用PHPExcel)
查看>>
最大连续子数列和问题
查看>>
职场技巧:Excel操作大全(转)
查看>>
codeforces 497b// Tennis Game// Codeforces Round #283(Div. 1)
查看>>
首页列表显示全部问答,完成问答详情页布局
查看>>
关于 Xcode8打印JSON的时候,NSLog控制台显示不完整
查看>>
js 弹出DIV层和关闭DIV层
查看>>
js中bind、call、apply函数的用法
查看>>
字符编码
查看>>
No address associated with hostname
查看>>
Novikoff定理
查看>>
android单元测试中的多线程以及handler消息传递
查看>>
3.App Resources-Resource Types/More Types
查看>>
获取异常信息
查看>>
golang包管理工具glide安装
查看>>
and 与 && or 与 || 的差异之处
查看>>
Study Plan - The Thirty-First Day
查看>>
关闭端口
查看>>