orm工具saveOrUpdate()操作设计思路

2024-02-29 22:20

本文主要是介绍orm工具saveOrUpdate()操作设计思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

当我们使用数据库向表中插入数据的时候,经常遇到这样的情况:

  1. 判断数据是否存在;
  2. 如果不存在,则插入;
  3. 如果存在,则更新。

如何设计saveOrUpdate()

当我们手写一个orm工具库的时候,我们都希望尽可能降低API的使用难度,合并更新和插入操作,那么我们应该如何设计saveOrUpdate操作呢?典型地,我们有以下几种思路。

1,利用数据库本身的sql标准

例如mysql的replace into函数。这种做法最简单,但因为绑定mysql数据库,无法做到通用。

replace into 跟 insert 功能类似,不同点在于:replace into首先尝试插入数据到表中,如果发现表中已经有此行数据(根据主键或者唯一索引判断),则先删除此行数据,然后插入新的数据。 否则,直接插入新数据。

2,在orm工具的实体类增加一个内存状态字段,表示是否已经存在于数据库

当记录从数据库读取出来,或者插入动作已经执行完毕,则执行更新操作;否则,执行插入操作。

jforgame框架里面的orm工具库采用这种设计思路。

3,利用jdbc的api

orm工具不管数据库有没有存在指定记录,先执行更新操作,如果操作成功,则无须执行插入动作。如果操作失败,则说明当前数据表不存在指定记录,需要执行插入动作。

public interface Statement extends Wrapper, AutoCloseable {// 如果方法返回值大于0,表示此次操作有影响的行数,更新有效int executeUpdate(String sql) throws SQLException {}
}

相应的设计伪代码如下所示:

if (DbUtil.executeUpdate(sql) <= 0) { //执行更新无效DbUtil.executeInsert(sql);   //执行更新插入
}

由于游戏服务器大部分是对实体执行更新操作,这种方式只会对记录第一次插入的时候会有性能影响,多了一步先行判断。

4,动态sql二次判断

跟第三种方式有点类似,首先,需要查询对象是否存在于数据库中。如果对象存在,则执行更新操作;如果对象不存在,则执行插入操作。伪代码如下:

public void saveOrUpdate(MyObject obj) {MyObject existingObj = sqlSession.selectOne("findObjectById", obj.getId());if (existingObj != null) {sqlSession.update("updateObject", obj);} else {sqlSession.insert("insertObject", obj);}
}

5,Hibernate的实现(智能但复杂,且有坑)

Hibernate在执行saveOrUpdate方法时,会根据对象的状态来决定是否进行插入或更新操作。如果对象处于临时状态,即没有关联到任何持久化对象,Hibernate会将该对象插入到数据库中;如果对象处于游离状态,即关联到一个持久化对象,但是没有通过Hibernate的session进行管理,Hibernate会将该对象更新到数据库中。

总之,Hibernate的saveOrUpdate方法是根据对象的标识符来判断对象是临时对象还是持久化对象,并根据对象的状态来决定进行插入或更新操作。

这篇关于orm工具saveOrUpdate()操作设计思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760297

相关文章

基于C++的UDP网络通信系统设计与实现详解

《基于C++的UDP网络通信系统设计与实现详解》在网络编程领域,UDP作为一种无连接的传输层协议,以其高效、低延迟的特性在实时性要求高的应用场景中占据重要地位,下面我们就来看看如何从零开始构建一个完整... 目录前言一、UDP服务器UdpServer.hpp1.1 基本框架设计1.2 初始化函数Init详解

python版本切换工具pyenv的安装及用法

《python版本切换工具pyenv的安装及用法》Pyenv是管理Python版本的最佳工具之一,特别适合开发者和需要切换多个Python版本的用户,:本文主要介绍python版本切换工具pyen... 目录Pyenv 是什么?安装 Pyenv(MACOS)使用 Homebrew:配置 shell(zsh

MySQL游标和触发器的操作流程

《MySQL游标和触发器的操作流程》本文介绍了MySQL中的游标和触发器的使用方法,游标可以对查询结果集进行逐行处理,而触发器则可以在数据表发生更改时自动执行预定义的操作,感兴趣的朋友跟随小编一起看看... 目录游标游标的操作流程1. 定义游标2.打开游标3.利用游标检索数据4.关闭游标例题触发器触发器的基

在C#中分离饼图的某个区域的操作指南

《在C#中分离饼图的某个区域的操作指南》在处理Excel饼图时,我们可能需要将饼图的各个部分分离出来,以使它们更加醒目,Spire.XLS提供了Series.DataFormat.Percent属性,... 目录引言如何设置饼图各分片之间分离宽度的代码示例:从整个饼图中分离单个分片的代码示例:引言在处理

Python列表的创建与删除的操作指南

《Python列表的创建与删除的操作指南》列表(list)是Python中最常用、最灵活的内置数据结构之一,它支持动态扩容、混合类型、嵌套结构,几乎无处不在,但你真的会创建和删除列表吗,本文给大家介绍... 目录一、前言二、列表的创建方式1. 字面量语法(最常用)2. 使用list()构造器3. 列表推导式

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

Python+wxPython开发一个文件属性比对工具

《Python+wxPython开发一个文件属性比对工具》在日常的文件管理工作中,我们经常会遇到同一个文件存在多个版本,或者需要验证备份文件与源文件是否一致,下面我们就来看看如何使用wxPython模... 目录引言项目背景与需求应用场景核心需求运行结果技术选型程序设计界面布局核心功能模块关键代码解析文件大

MySQL基本表查询操作汇总之单表查询+多表操作大全

《MySQL基本表查询操作汇总之单表查询+多表操作大全》本文全面介绍了MySQL单表查询与多表操作的关键技术,包括基本语法、高级查询、表别名使用、多表连接及子查询等,并提供了丰富的实例,感兴趣的朋友跟... 目录一、单表查询整合(一)通用模版展示(二)举例说明(三)注意事项(四)Mapper简单举例简单查询

Nginx概念、架构、配置与虚拟主机实战操作指南

《Nginx概念、架构、配置与虚拟主机实战操作指南》Nginx是一个高性能的HTTP服务器、反向代理服务器、负载均衡器和IMAP/POP3/SMTP代理服务器,它支持高并发连接,资源占用低,功能全面且... 目录Nginx 深度解析:概念、架构、配置与虚拟主机实战一、Nginx 的概念二、Nginx 的特点