本文主要是介绍orm工具saveOrUpdate()操作设计思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
背景
当我们使用数据库向表中插入数据的时候,经常遇到这样的情况:
- 判断数据是否存在;
- 如果不存在,则插入;
- 如果存在,则更新。
如何设计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()操作设计思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!