zoukankan      html  css  js  c++  java
  • Hibernate中的session对象update方法的使用

    使一个游离对象转变为持久化对象。例如以下代码在session1中保存了一个Customer对象,然后在session2中更新这个Customer对象:

    Customer customer = new Customer();

    customer.setName("Tom");

    Session session1 = sessionFactory.buildSession();

    Transaction tx1 = session.beginTransaction();

    session1.save(customer);

    tx1.commit();

    session1.close();

    Session session2 = sessionFactory.openSession();

    Transaction tx2 = session2.beginTransaction();

    customer.setName("Linda"); // 在和session2关联之前修改Customer对象的属性

    session2.update(customer);

    customer2.setName("Jack"); // 在和session2关联之后修改Customer对象的属性

    tx2.commit();

    session2.close();

    Session的update()方法完成以下操作:

    (1)把Customer对象重新加入到Session的缓存中,使它变为持久化对象。

    (2)计划执行一个update语句。值得注意的是,Session只有在清理缓存的时候才会执行update语句,并且在执行时才会把Customer对象当前的属性值组装到update语句中。因此,即使程序中多次修改了Customer对象的属性,在清理缓存时只会执行一次update语句。以下两段代码是等价的,无论是左边的代码,还是右边的代码,Session都只会执行一条update语句:

    ......

    Session session2 = sessionFactory.openSession();

    Transaction tx2 = session2.beginTransaction();

    customer2.setName("Linda");

    session.update(customer);

    customer.setName("Jack");

    tx2.commit();

    session2.close();

    ......

    Session session2 = sessionFactory.openSession();

    Transaction tx2 = session1.beginTransaction();

    session2.update(customer);

    customer.setName("Linda");

    customer.setName("Jack");

    txt2.commit();

    session2.close();

    以上代码尽管把Customer对象的name属性修改了两次,但Session在清理缓存时,根据Customer对象的当前属性值来组装update语句,因此执行的update语句为:

    update CUSTOMERS set name='Jack' ...... where ID=1;

    只要通过update()方法使游离对象被一个Session关联,即使没有修改Customer对象的任何属性,Session在清理缓存时也会执行由update()方法计划的update语句。例如以下程序使Customer对象被session2关联,但是没有修改Customer对象的任何属性:

    // 此处省略session1持久化Customer对象的代码

    Session session2 = sessionFactory.openSession();

    Transaction tx2 = session2.beginTransaction();

    session.update(customer);

    txt2.commit();

    session2.close();

    Session在清理存缓时,会执行由update()方法计划的update语句,并且根据Customer对象的当前属性来组装update语句:

    update CUSTOMERS set name='Tom' ...... where ID=1;

    如果希望Session仅仅当修改了Customer对象的属性时,才执行update语句,可以把映射文件中<class>元素的select-before-update设为true,该属性默认值为false:

    <class name="Customer" table="CUSTOMERS" selecet-before-update="true">

      如果按以上方式修改了Customer.hbm.xml文件,当Session清理缓存时,会先执行一条select语句:

    select * from CUSTOMERS where ID=1;

    然后比较Customer对象的属性是否和从数据库中检索出来的记录一致,只有在不一致的情况下,才执行update语句。

    应用根据实际情况来决定是否应该把select-before-update设为true。如果Java对象的属性不会经常变化,可以把select-before-update属性设为true,避免Session执行不必要的update语句,这样会提高应用程序的性能。如果需要经常修改Java对象的属性,就没必要把这个属性设为true,因为它会导致在执行update语句之前,执行一条多余的select语句。

    当update()方法关联一个游离对象时,如果在Session的缓存中已经存在相同OID的持久化对象,会抛出异常。例如以下代码通过session2加载了OID为1的Customer对象,接下来又试图把一个OID为1的Customer游离对象加入到session2的缓存中:

    // 此处省略session1持久化Customer对象的代码

    ......

    Session session2 = sessionFactory.openSession();

    Transaction tx2 = session2.beginTransaction();

    // session2加载一个OID为1的Customer持久化对象

    Customer anotherCustomer = (Customer)session2.load(Customer.class, new Long(1));

    // 把一个OID为1的Customer游离对象加入到session2的缓存中

    session2.update(customer);

    tx2.commit();

    session2.close();

    当执行session2的update()方法时,由于session2的缓存中已经存在了OID为1的Customer持久化对象,因此不允许把OID为1的Customer游离对象再加入到session2的缓存中,Session在运行时会抛出异常。此外,当update()方法关联一个游离对象时,如果在数据库中不存在相应的记录,也会抛出异常。

  • 相关阅读:
    一次性解决window系统下,git日志乱码的问题
    多线程之线程状态,状态切换种类及代码实例
    mybatis 第一个demo,并记一次解决问题:Mapped Statements collection does not contain value for
    有100盏灯,分别写上编号1~100,同样地 有100个开关,写上编号1~100。当我按1号开关,写上1的倍数的灯会开/关(如果灯开着就关,相反地,关着就会开),当我按2号开关,写上2的倍数的灯会开/关,如此类推
    阿里云云服务器 centos 7.4 安装mysql 过程记录
    java实现树形输出
    MATLAB入门笔记
    经测试稳定可用的蓝牙链接通信Demo,记录过程中遇到的问题的思考和解决办法,并整理后给出一个Utils类可以简单调用来实现蓝牙功能
    View的相关原理(读书笔记)
    JAVA设计方法思考之如何实现一个方法执行完毕后自动执行下一个方法
  • 原文地址:https://www.cnblogs.com/xiohao/p/3614491.html
Copyright © 2011-2022 走看看