Hibernate中Session增删改查操作代码详解
作者:街灯下的小草 发布时间:2022-12-25 17:14:22
把三状态转换图放在这,方便分析方法的作用:
1.Session的save()方法
Session是Hibernate所有接口中最重要的接口,提供了对数据保存,更新,查询和删除的方法。
Session的save()方法可以使临时态或游离态转换为持久态。例如,保存一个Customer对象:
SessionFactory sessionFactory;
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
//1.创建Customer对象
Customer c1 = new Customer();
c1.setId(new long(1));
c1.setName("test");
c1.setEmail("123456789@qq.com");
c1.setPassword("123456");
c1.setAddress("世外桃源");
//2.调用Session的save()方法,将Customer对象持久化
session.save(c1);
tr.commit();
session.close();
Save()方法主要做了以下三件事:
(1)将new创建的临时态的Customer对象放入缓存,使其持久化。
(2)同时根据对象关系映射文件中设置的OID生成器,即主键生成方式给该对象生成一个唯一的OID。
<!--设置主键-->
<idname="id"column="ID"type="long">
<!--主键生成方式-->
<generatorclass="increment"/>
</id>
在这个地方有一个疑问,创建对象时setId()方法是否是为该对象持久化生成主键,其实不是,setId并没有按照我们设定的那样生成主键,而是靠对象关系映射文件配置的主键生成方式生成主键,可以多运行几次,主键自增长,从数据库可以看到多条数据,主键从1开始,所以可以知道setId()
没有设置主键,否则数据库主键唯一性校验都过不去。
我们也可以手动设置主键值,必须重载save()方法,使用重载方法save(c1,newLong(1)),每次手动设置。
(3)计划执行insert语句。注意,insert语句并没有立刻执行,只有当Session清理缓存时,才会执行insert语句。tr.commit()事务提交。
2.Session的update()方法
使游离态对象变成持久态对象。例如:
SessionFactory sessionFactory;
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
Session session1 = sessionFactory.openSession();
Transaction tr1 = session1.beginTransaction();
//1.创建Customer对象
Customer c1 = new Customer();
c1.setId(new Long(1));
c1.setName("test");
c1.setEmail("123456789@qq.com");
c1.setPassword("123456");
c1.setAddress("世外桃源");
//2.调用Session的save()方法,将Customer对象持久化
session1.save(c1);
tr1.commit();
session1.close();
//3.将游离态的对象更新,发现改变,执行update语句
Session session2 = sessionFactory.openSession();
Transaction tr2 = session2.beginTransaction();
c1.setAddress("测试update");
session2.update(c1);
tr2.commit();
session2.close();
Session的update()注意做以下事:
(1)把游离态的Customer对象从新加入Session缓存中,使其变成持久化对象。
(2)执行update语句。跟save()执行insert语句一样,并不是立刻执行update语句,需要等缓存清空时,把Customer对象组装成update语句,
然后再执行。
注意,即使Customer没有改变,默认情况下,缓存清除时也会组装Update语句,如果需要设置成改变成才执行update语句,需要设置对象关系映射文件。
3.Session的saveOrUpdate()方法
saveOrUpdate()方法包含save()和update()方法的功能,根据传入参数状态,调用不同方法。传入临时态对象调用save()方法,如果传入游离态对象调用
update()方法。传入持久态对象返回。所以,每次我们只需传入对象,saveOrUpdate()方法,自动判断传入对象状态的状态,动态调用处理方法。
该方法如何判断传入对象的状态?当满足以下任意一个条件时,就是临时态:
(1)java对象的OID为null,说明该对象没有别实例化,即使被实例化,也是游离态被删除后变成临时态的对象,这种情况下的对象为临时态。
(2)如果java对象具有版本控制(version),版本号为null的,也就是没有该对象的版本号。
(3)自定义 * ,调用isUnsaved()返回值为true。
4.Session的load()和get()方法
这两个方法都是根据OID,从数据库中加载一个持久化对象。持久化对象放在Session缓存中,可以根据不同的需要操作该持久化对象。
两者区别:
当数据库中OID没有对应记录时,load()抛异常,get()返回null。
5.Session的delete()方法
delete()顾名思义删除,用于从数据库中删除java对象对应的记录。
delete()如果传入持久化对象,组装delete语句,执行删除;如果传入游离态对象,hibernate先把游离态关联到session,变成持久态,再生成delete语句,
执行删除。
都是只有当session缓存清空时,才执行。
以上执行都是一个对象,对应一条记录。
可以用session.delete("fromCustomerwhere....");后面加上条件删除多条数据。
SessionFactory sessionFactory;
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
Session session1 = sessionFactory.openSession();
Transaction tr1 = session1.beginTransaction();
//1.创建Customer对象
Customer c1 = new Customer();
c1.setId(new Long(1));
c1.setName("test");
c1.setEmail("123456789@qq.com");
c1.setPassword("123456");
c1.setAddress("世外桃源");
//2.调用Session的save()方法,将Customer对象持久化
session1.save(c1);
tr1.commit();
session1.close();
//3.将游离态的对象关联到session,持久化后清除缓存,执行delete语句;放入持久态的直接删除;
Session session2 = sessionFactory.openSession();
Transaction tr2 = session2.beginTransaction();
session2.delete(c1);
tr2.commit();
session2.close();
执行结果,控制台输出:
Hibernate: select max(ID) from CUSTOMERS
Hibernate: insert into CUSTOMERS (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, DESCRIPTION, IMAGE, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: delete from CUSTOMERS where ID=?
来源:http://blog.csdn.net/yhl_jxy/article/details/50685648


猜你喜欢
- FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化
- 在日常开发中我们经常会使用到行情数据,很多的时候我们根据一个基准数据区构造行情,但是随着时间的推移然来构造的数据与真实行情数据之间的差距越来
- 本文实例为大家分享了UnityShader3实现彩光效果展示的具体代码,供大家参考,具体内容如下参考链接: 【OpenGL】Shader实例
- 最近要实现一个功能,就是checkbox跨页多选,在网上看了一下,资料很少,而且大多是不完全的。不过经过我的努力,终于做出来了。
- socketpair()函数的声明:#include <sys/types.h>#include <sys/socket.
- 使用正则表达式进行替换:代码片段:String documentTxt = EntityUtils.toString(entity,&quo
- 在android中的webview中,可以对文本内容进行对齐,具体方法如下 public class MainActivity
- 如果JDBC连接是在自动提交模式下,它在默认情况下,那么每个SQL语句都是在其完成时提交到数据库。这可能是对简单的应用程序,但有三个原因,你
- 一、定义一个配置类,自定义RedisTemplate的序列化方式@Configurationpublic class RedisConfig
- LeetCode -- Path Sum III分析及实现方法题目描述:You are given a binary tree in whi
- Mybatis采用责任链模式,通过 * 组织多个 * (插件),通过这些 * 可以改变Mybatis的默认行为(诸如SQL重写之类的),由
- Swing包的介绍Java基础类数据库(Java Foundation Class)给java应用程序增加了图形界面、丰富的功能性以及与用户
- 前言项目使用了SpringBoot构建项目。下面对动态调整日志的级别进行记录。从版本 1.5.1 之后就提供了基于 spring-boot-
- 前言Bitmap相信对各位Android开发者们来说都不陌生,用它可以获取图片信息,进行图片剪切、平移、旋转、缩放等操作,并可以指定格式保存
- 前言App安全非常重要,尤其是数据安全。但是我们知道通过Charles等工具可以对App的网络请求进行抓包,如果我们的数据没有进行加密,这样
- byte:java中最小的数据类型。1字节/8位。-128(2^7)~127(2^7-1),默认值0。short:短整型,2字节/16位,取
- 命令模式定义:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志来参数化其他对象。何时使用命令模式?当需要将发出请求的对象和执行请求
- 前言前段时间看到一道面试题:“main函数可以被重载么?”,当时就蒙圈了,怎么还会有这种面试题,现在
- 截取字符串最后一位1.用substring()来截取理论上它是按照字符串.substring(字符串.lastIndexOf("\
- 一、回顾Stream管道流操作通过前面章节的学习,我们应该明白了Stream管道流的基本操作。我们来回顾一下:源操作:可以将数组、集合类、行