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

相关文章

Python调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

Java中基于注解的代码生成工具MapStruct映射使用详解

《Java中基于注解的代码生成工具MapStruct映射使用详解》MapStruct作为一个基于注解的代码生成工具,为我们提供了一种更加优雅、高效的解决方案,本文主要为大家介绍了它的具体使用,感兴趣... 目录介绍优缺点优点缺点核心注解及详细使用语法说明@Mapper@Mapping@Mappings@Co

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、