Hibernate更新数据(不用update也可以)
在介绍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也可以)的更多相关文章
- MySQL 误删数据、误更新数据(update,delete忘加where条件)
MySQL 误操作后数据恢复(update,delete忘加where条件) 关键词:mysql误删数据,mysql误更新数据 转自:https://www.cnblogs.com/gomysql/p ...
- Mysql 一条SQL语句实现批量更新数据,update结合case、when和then的使用案例
如何用一条sql语句实现批量更新?mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现. 复制代码 代码如下: UPDATE mytable SET myfield = CASE i ...
- 七十九、SAP中数据库操作之更新数据,UPDATE的用法
一.我们查看SFLIGHT数据库,比如我们需要改这条数据 二.代码如下 三.执行效果如下,显示“数据更新成功” 四.我们来看一下SFLIGHT数据库,发现已经由DEM更改为了AAA了
- django 里面的更新数据(update)
https://blog.csdn.net/qq_42606051/article/details/81162189 https://blog.csdn.net/luojie140/article/d ...
- 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 ...
- python + mysql 实现表更新数据
实例如下: import pymysqldef Update_Set(): #打开数据库链接 db = pymysql.connect("localhost","root ...
- hibernate persist update 方法没有正常工作(不保存数据,不更新数据)
工程结构 问题描述 在工程中通过spring aop的方式配置事务,使用hibernate做持久化.在代码实现中使用hibernate persit()方法插入数据到数据库,使用hibernate u ...
- 解决Hibernate4执行update操作,不更新数据的问题
后台封装java对象,使用hibernate4再带的update,执行不更新数据,不报错. 下面贴出解决方法: 失败的方法 hibernate自带update代码:(失效) Session sessi ...
- MySQL行(记录)的详细操作一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理
MySQL行(记录)的详细操作 阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: ...
随机推荐
- Nginx原理和配置总结
一:前言 Nginx是一款优秀的HTTP服务器和反向代理服务器,除却网上说的效率高之类的优点,个人的切身体会是Nginx配置确实简单而且还好理解,和redis差不多,比rabbitmq好理解太多了: ...
- Spring Security入门(1-12)Spring Security 的过滤器机制
Servlet过滤器被用来拦截用户请求来进行请求之前或之后的处理,或者干脆重定向这个请求,这取决于servlet过滤器的功能. Servlet过滤器处理之后的目标servlet是 MVC 分发web ...
- vue组件详解(五)——组件高级用法
一.递归组件 组件在它的模板内可以递归地调用自己, 只要给组件设置name 的选项就可以了. 示例如下: <div id="app19"> <my-compone ...
- Scala:枚举类型的用法
枚举定义: /** * 场景类型的划分分类:划分出7类 */ object BuildingCalibrateHeightType extends Enumeration { type Buildin ...
- filter过滤器与map映射
filter过滤器 >>> list(filter(None,[0,1,2,True,False])) [1, 2, True] filter的作用就是后面的数据按照前面的表达式运算 ...
- hue集成hive访问报database is locked
这个问题这应该是hue默认的SQLite数据库出现错误,你可以使用mysql postgresql等来替换 hue默认使用sqlite作为元数据库,不推荐在生产环境中使用.会经常出现database ...
- iOS之AFSecurityPolicy
AFSecurityPolicy是AFNetworking中负责对https请求进行证书验证的模块,本文主要是要搞清楚它是如何工作的. 在介绍AFSecurityPolicy之前,我们先来了解一下ht ...
- [LeetCode] Network Delay Time 网络延迟时间
There are N network nodes, labelled 1 to N. Given times, a list of travel times as directed edges ti ...
- 机器学习技法:10 Random Forest
Roadmap Random Forest Algorithm Out-Of-Bag Estimate Feature Selection Random Forest in Action Summar ...
- 【实验吧】CTF_Web_登录一下好吗?
实验吧CTF---Web篇 1. 打开登录地址(http://ctf5.shiyanbar.com/web/wonderkun/web/index.html),发现为一个登录界面,第一想到的是查看源代 ...