在介绍hibernate的更新之前,我们先来看看session的两个方法。load和get方法;这两个方法是获取数据的根据对象的id值;

先看两段代码。load和get的方法都含有两个参数,前者是得到的对象类型。后者是一个可序列化的值,说白了也就是你要获取数据库里面对应的主键的值,你的主键如果是id。你获取的是第一条记录那么则是一,如果你的主键是name。你就写上某个名字。然后获取这个名字对应的数据记录。

当我们执行下面两条语句的时候,我们会发现第一条报错。而第二条是没有什么问题的。

但是如果我们把两个里面的打印语句都写到commit之前的时候。我们发现两个都不会报错了。

@Test
public void testload(){
Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction(); Teacher t=(Teacher) session.load(Teacher.class, 1);
session.getTransaction().commit();
System.out.println(t.getName());
} @Test
public void testget(){
Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction(); Teacher t=(Teacher) session.get(Teacher.class, 1);
session.getTransaction().commit();
System.out.println(t.getName()); }

  

这里面是有原因的。当用load获取的时候,其实执行load语句只是将对象置入到内存中。而执行get方法的时候。不但将对象放入到了内存而且。对象执行了sql语句。对象的值已经在getName方法执行已经赋值了。而load方法。在执行getName方法的时候才执行sql语句,从数据库里面获取相关的记录。当我们在执行getName方法前后加上时间的时候。我们得到时间差的话我们会发现,我load这种情况下getName费许多的时间。而get这种情况几乎没有费什么时间。

那么为什么在提交之后,load得到getName的方法会出错呢。那是因为提交完之后。当前的session自动关闭了。当然这是getCurrentSession的情况下。而再去调用镀锡的getName方法的时候。session对象关闭了。相等于缓存中没有对应的记录了。只有数据库和内存中有。此时再无获取getname的时候没有中间桥梁session。那么肯定出错。而get方法的话。因为已经在get方法执行的时候将数据赋值给了对象。那么我们获取的时候直接从内存里面拿去好了。用不着经由session去访问数据库。所以不会出错。

下面来具体谈谈更新数据的情况

更新数据我们的第一反应是从数据库里面讲数据拿出来然后改变某些值,然后再调用update的方法完成操作。这种方法是对的。但是不是只有这一种方法的。我们还有不通过调用update方法就可以完成更新。update方法里面传入的对象。一定要有主键的值。并且主键的记录一定可以在数据库里面找得到,这样才不会报错的。所以我们可以先不用从数据库里面拿去对象。而是先定义一个对象。之后再给此对象赋值。然后更新此对象。如果给的值在数据库中含有那么对应的记录也可以然后更新。

1.常规方法先从数据库里面拿取,然后更新

Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction(); Teacher t=(Teacher) session.get(Teacher.class, 1);
t.setName("wsx");
session.update(t) session.getTransaction().commit();

  

2.先创建一个对象,然后给其赋值。再更新。

Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction(); Teacher t=new Teacher();
t.setName("wsx");
session.update(t)
session.getTransaction().commit();

以上这两种方法都可以完成更新的操作。

而以下的这种方法也是可以完成更新的。并且没有用到update方法;

Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction(); Teacher t=(Teacher) session.get(Teacher.class, 1);
t.setName("wsx");
session.getTransaction().commit();

我们仔细瞧下来会发现。它与第一个方法的不同之处就是没有用到update方法。难道这也行吗?嗯。我肯定的告诉你。

接下来我们探究其道理。

当我们执行get方法的时候,其实在内存中,缓存session中,数据库中都有对应的Teacher对象。而当我们改变其内存中对象的名字的时候。我们再提交的话,其实是数据库事务会去检测,内存中的session对象的值和缓存session中的值是否一致,不一致的话,那么则提交更新。

更新数据时遇到的问题。

我们会发现更新数据的时候。如果一个表中有五个字段,而我们只更新一个字段比较说更新年龄字段的时候。那么我们会从打印日志中惊奇的发现我们的其他几个字段也更新了。这种更新方式是很不友好的。代价也很巨大。也许本来你只需更新一个年龄的值。而其他字段里面有一篇文章。那么你只简简单单更新一个年龄却引起一篇文章的更新。

根据这一问题,我们有一些几个解决问题的办法

1.通过annotation在某个不需要更新的字段的get方法之前加上@column(updatable=false);

@Column(updatable=false)
ublic String getName() {
return name;

这种方法的缺点是这个字段永远不会更新。这个我们一想就感觉很不灵活。也许某一天这个字段需要更新。但是也有永不更新的情况。这个很多。比如一个银行的名字。等待。

2.在xml配置文件里面class加上dynamic——update=true;

Xml代码

<hibernate-mapping>
<class name="com.bjsxt.hibernate.Student" dynamic-update="true">
<id name="id" column="id"/>
<property name="name" />
<property name="age" />
</class> </hibernate-mapping>

这样就会自动更新。但是我们的自动更新某些需要更新的列的话,我们必须要在同一个session中。不同的session。找不到参考依据的话,那么也会集体更新的。

@Test
public void testupdate1(){
Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction();
Teacher t=(Teacher) session.get(Teacher.class, 1);
t.setName("wsx");
session.update(t);
session.getTransaction().commit(); t.setName("wsx1");
Session session1 =null;
session1 =sessionFactory.getCurrentSession();
session1.beginTransaction();
session.update(t);
session.getTransaction().commit();
}

  

第一个session的update方法只会更新name。而第二个全部属性都会更新;

3.用hql语句。你需要更新那个列,那么则写成相应的形式;

Java代码
@Test
public void testupdate2(){
Session session =null;
session =sessionFactory.getCurrentSession();
session.beginTransaction(); Query q=session.createQuery("update tablename set name='wsx' where id=1 ");
q.executeUpdate();
session.getTransaction().commit(); }

  

我们很多情况下用到第三种方式。 好了更新就讲到这儿。

Hibernate更新数据(不用update也可以)的更多相关文章

  1. MySQL 误删数据、误更新数据(update,delete忘加where条件)

    MySQL 误操作后数据恢复(update,delete忘加where条件) 关键词:mysql误删数据,mysql误更新数据 转自:https://www.cnblogs.com/gomysql/p ...

  2. Mysql 一条SQL语句实现批量更新数据,update结合case、when和then的使用案例

    如何用一条sql语句实现批量更新?mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现. 复制代码 代码如下: UPDATE mytable SET myfield = CASE i ...

  3. 七十九、SAP中数据库操作之更新数据,UPDATE的用法

    一.我们查看SFLIGHT数据库,比如我们需要改这条数据 二.代码如下 三.执行效果如下,显示“数据更新成功” 四.我们来看一下SFLIGHT数据库,发现已经由DEM更改为了AAA了

  4. django 里面的更新数据(update)

    https://blog.csdn.net/qq_42606051/article/details/81162189 https://blog.csdn.net/luojie140/article/d ...

  5. Hibernate更新数据报错:a different object with the same identifier value was already associated with the session: [com.elec.domain.ElecCommonMsg#297e35035c28c368015c28c3e6780001]

    使用hibernate更新数据时,报错 Struts has detected an unhandled exception: Messages: a different object with th ...

  6. python + mysql 实现表更新数据

    实例如下: import pymysqldef Update_Set(): #打开数据库链接 db = pymysql.connect("localhost","root ...

  7. hibernate persist update 方法没有正常工作(不保存数据,不更新数据)

    工程结构 问题描述 在工程中通过spring aop的方式配置事务,使用hibernate做持久化.在代码实现中使用hibernate persit()方法插入数据到数据库,使用hibernate u ...

  8. 解决Hibernate4执行update操作,不更新数据的问题

    后台封装java对象,使用hibernate4再带的update,执行不更新数据,不报错. 下面贴出解决方法: 失败的方法 hibernate自带update代码:(失效) Session sessi ...

  9. MySQL行(记录)的详细操作一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理

    MySQL行(记录)的详细操作 阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: ...

随机推荐

  1. 非PE病毒介绍

    1.宏病毒 1.1 介绍 本文中的宏特制office系列办公软件中的宏,Microsoft Office中对宏的定义为"宏就是能够组织在一起的,可以作为一个独立命令来执行的一系列Word 命 ...

  2. IDEA安装和JDK的配置

    安装: 免费获取注册码:   http://idea.lanyus.com/ 将其压缩包解压后:  应用程序在bin目录下 打开之后: 选择第二个,输入刚获取的验证码: 成功. 如果没有安装JDK报错 ...

  3. Python scrapy框架

    Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设 ...

  4. Java-NIO(六):Channel聚集(gather)写入与分散(scatter)读取

    Channel聚集(gather)写入: 聚集写入( Gathering Writes)是指将多个 Buffer 中的数据“聚集”到 Channel. 特别注意:按照缓冲区的顺序,写入 positio ...

  5. Spark:导入数据到oracle

    方案一: //overwrite JdbcDialect fitting for Oracle val OracleDialect = new JdbcDialect { override def c ...

  6. Hibernate(十三):HQL查询(二)

    背景 基于上一章节<Hibernate(十二):HQL查询(一)>,已经学习了一部分关于HQL的用法: HQL带参数查询 HQL Order By排序查询 HQL 设置实体参数查询 本章节 ...

  7. Java:import com.sun.awt.AWTUtilities;报错

    参考网址:http://stackoverflow.com/questions/860187/access-restriction-on-class-due-to-restriction-on-req ...

  8. Ubuntu16.04开机引导缺失Win10

    Ubuntu正常开机的情况下: sudo update-grub # 如果grub丢失, 就先sudo apt install grub Ubuntu不能正常开下: 进入Ubuntu引导, 不要正常进 ...

  9. Yii2 数据库操作汇总

    对象操作 查询 //1.简单查询 $admin=Admin::model()->findAll($condition,$params); $admin=Admin::model()->fi ...

  10. vue-router详解——小白速会

    一.概述 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用. vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来. ...