在介绍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. emqtt 试用(七)追踪

    追踪 EMQ 消息服务器支持追踪来自某个客户端(Client)的全部报文,或者发布到某个主题(Topic)的全部消息. 追踪客户端(Client): ./bin/emqttd_ctl trace cl ...

  2. 单点登录实现机制:桌面sso

    参考链接,感谢作者:https://zm10.sm-tc.cn/?src=l4uLj8XQ0IiIiNGckZ2TkJiM0ZyQktCZlo2Mi5uNmp6S0I/QysrJyszPztGXi5K ...

  3. global文件中的application_start方法中做: 定时器

    <%@ Application Language="C#" %> <%@ import Namespace="System.Data" %&g ...

  4. HTNL表单详解

    HTML表单 表单的结构 表单的标签:<form> </form> 常用属性 Name , method(get,post), action(服务器的接收的页面如:reg.ph ...

  5. 关于tr069网管开发系列教程

    原创作品,转载请注明出处,严禁非法转载.如有错误,请留言! email:40879506@qq.com 声明:本系列涉及的开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅 ...

  6. 收藏:视频网站(JavaEE+FFmpeg)/Nginx+ffmpeg实现流媒体直播点播系统

    FFmpeg安装(windows环境)http://www.cnblogs.com/xiezhidong/p/6924775.html 最简单的视频网站(JavaEE+FFmpeg)http://bl ...

  7. 1.4WEB API 路由配置及参数传输

    在没有添加路由时,webapi 的访问比较恶心,访问的时候是没有接口方法的.如果定义了同样参数的方法,它就傻傻的分不清的,为了解决这个问题,我们加上路由吧. 这是生成的api帮助文档列表,可以看到下面 ...

  8. EF5中 执行 sql语句使用Database.ExecuteSqlCommand 返回影响的行数 ; EF5执行sql查询语句 Database.SqlQuery 带返回值

    一: 执行sql语句,返回受影响的行数 在mysql里面,如果没有影响,那么返回行数为  -1 ,sqlserver 里面  还没有测试过 using (var ctx = new MyDbConte ...

  9. java设计模式之单例设计模式和多例设计模式

    单例设计模式:构造方法私有化,在类的内部定义static属性和方法,利用static方法来取得本类的实例化对象:无论外部产生多少个实例化对象,本质上只有一个实例化对象 饿汉式单例设计 class Si ...

  10. 妙用 scale 与 transfrom-origin,精准控制动画方向

    上次发完 不可思议的纯 CSS 导航栏下划线跟随效果 这篇文章之后,很多朋友找我讨论,感叹 CSS 的奇妙. 然后昨天,群里一位朋友问到了一个和这个效果比较类似的效果,问如何 将下面这个动画的下划线效 ...