在介绍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. 英语日常词汇:living-room、dining-room vs dining hall

    hall 大厅 : living room起居室,客厅 : dining room餐厅.饭厅 dining room是家里的客厅,比较小啊,dining hall一般指酒店或宾馆啊什么的的大厅,宴客厅

  2. 使用 HttpClient3.1 和 HtmlParser2.1 开发Crawler

    https://www.ibm.com/developerworks/cn/opensource/os-cn-crawler/

  3. maven入门(9)Maven常用命令

    Maven常用命令 清理 clean编译 compile打包 package安装 install跳过测试 clean package -Dmaven.test.skip=true

  4. jenkins配置findbugs失败---不要随便忽略警告!一个因为文件所有权引发的血案

    一:背景交代 这两天组长让我这边搭一个持续集成环境.梳理了需求后,因为我们的项目都是maven项目,所以我选择了jenkins+外置maven(区别于直接从jenkins里面安装)的方案.(cento ...

  5. django Form组件 上传文件

    上传文件 注意:FORM表单提交文件要有一个参数enctype="multipart/form-data" 普通上传: urls: url(r'^f1/',views.f1), u ...

  6. Tumblr:我们是如何从 PHP 5 升级到 PHP 7 的

    Tumblr 团队经常在寻找新的方式来提升网站的性能.这意味着要给访问量大的代码增加缓存,找到更快的 CDN 配置,或者升级基础软件. 最近,通过一次跨团队的努力,我们将全部 web 服务器战舰从 P ...

  7. global与nonlocal关键字总结

    global适用于函数内部修改全局变量的值 nonlocal适用于嵌套函数中内部函数修改外部变量的值 如果没有使用以上关键字,对全局变量或者外部变量进行修改,python会默认将全局变量隐藏起来 例1 ...

  8. border三角形阴影(不规则图形阴影)和多重边框的制作

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 1. border的组合写法 border:border-width border-style borde ...

  9. building a new horizon

    昨天是4月14日,也是我的23岁生日.正好去参加GDG举办的WTM,这次的主题是building a new horizon. 写一下印象深刻的分享者和她们的闪光点. 1.羡辙-从灵感到落地 羡辙是在 ...

  10. 浅析java的深拷贝与浅拷贝

    (转自:http://www.cnblogs.com/chenssy/p/3308489.html) 首先来看看浅拷贝和深拷贝的定义: 浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式 ...