文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何使用ORM链式操作?如何优雅的实现软删除?

2024-12-01 12:39

关注

gdb模块支持对数据记录的写入、更新、删除时间自动填充,提高开发维护效率。为了便于时间字段名称、类型的统一维护,如果使用该特性,我们约定:

created_at用于保存记录的创建时间,仅会写入一次。

updated_at用于保存记录的修改时间,每次记录变更时更新。

deleted_at用于保存记录的软删除特性,只有当记录删除时会写入一次。

字段名称其实不区分大小写,也会忽略特殊字符,例如CreatedAt​,  UpdatedAt​,  DeletedAt​也是支持的。此外,时间字段名称可以通过配置文件进行自定义修改,并可使用TimeMaintainDisabled配置完整关闭该特性,具体请参考 ORM使用配置 章节。

对时间类型的固定其实是为了形成一种规范。

特性的启用

当数据表包含created_at、updated_at、deleted_at任意一个或多个字段时,该特性自动启用。

以下的示例中,我们默认示例中的数据表均包含了这3个字段。

​created_at​​写入时间

在执行Insert/InsertIgnore/BatchInsert/BatchInsertIgnore方法时自动写入该时间,随后保持不变。

// INSERT INTO `user`(`name`,`created_at`,`updated_at`) VALUES('john', `2020-06-06 21:00:00`, `2020-06-06 21:00:00`)
g.Model("user").Data(g.Map{"name": "john"}).Insert()

// INSERT IGNORE INTO `user`(`uid`,`name`,`created_at`,`updated_at`) VALUES(10000,'john', `2020-06-06 21:00:00`, `2020-06-06 21:00:00`)
g.Model("user").Data(g.Map{"uid": 10000, "name": "john"}).InsertIgnore()

// REPLACE INTO `user`(`uid`,`name`,`created_at`,`updated_at`) VALUES(10000,'john', `2020-06-06 21:00:00`, `2020-06-06 21:00:00`)
g.Model("user").Data(g.Map{"uid": 10000, "name": "john"}).Replace()

// INSERT INTO `user`(`uid`,`name`,`created_at`,`updated_at`) VALUES(10001,'john', `2020-06-06 21:00:00`, `2020-06-06 21:00:00`) ON DUPLICATE KEY UPDATE `uid`=VALUES(`uid`),`name`=VALUES(`name`),`updated_at`=VALUES(`updated_at`)
g.Model("user").Data(g.Map{"uid": 10001, "name": "john"}).Save()

需要注意的是Replace方法也会更新该字段,因为该操作相当于删除已存在的旧数据并重新写一条数据。

​updated_at​​更新时间

在执行Insert/InsertIgnore/BatchInsert/BatchInsertIgnore​方法时自动写入该时间,在执行Save/Update​时更新该时间(注意当写入数据存在时会更新updated_at​时间,不会更新created_at时间)。

// UPDATE `user` SET `name`='john guo',`updated_at`='2020-06-06 21:00:00' WHERE name='john'
g.Model("user").Data(g.Map{"name" : "john guo"}).Where("name", "john").Update()

// UPDATE `user` SET `status`=1,`updated_at`='2020-06-06 21:00:00' ORDER BY `login_time` asc LIMIT 10
g.Model("user").Data("status", 1).Order("login_time asc").Limit(10).Update()

// INSERT INTO `user`(`id`,`name`,`update_at`) VALUES(1,'john guo','2020-12-29 20:16:14') ON DUPLICATE KEY UPDATE `id`=VALUES(`id`),`name`=VALUES(`name`),`update_at`=VALUES(`update_at`)
g.Model("user").Data(g.Map{"id": 1, "name": "john guo"}).Save()

需要注意的是Replace方法也会更新该字段,因为该操作相当于删除已存在的旧数据并重新写一条数据。

​deleted_at​​数据软删除

软删除会稍微比较复杂一些,当软删除存在时,所有的查询语句都将会自动加上deleted_at的条件。

// UPDATE `user` SET `deleted_at`='2020-06-06 21:00:00' WHERE uid=10
g.Model("user").Where("uid", 10).Delete()

查询的时候会发生一些变化,例如:

// SELECT * FROM `user` WHERE uid>1 AND `deleted_at` IS NULL
g.Model("user").Where("uid>?", 1).All()

可以看到当数据表中存在deleted_at​字段时,所有涉及到该表的查询操作都将自动加上deleted_at IS NULL的条件

联表查询的场景

如果关联查询的几个表都启用了软删除特性时,会发生以下这种情况,即条件语句中会增加所有相关表的软删除时间判断。

// SELECT * FROM `user` AS `u` LEFT JOIN `user_detail` AS `ud` ON (ud.uid=u.uid) WHERE u.uid=10 AND `u`.`deleted_at` IS NULL AND `ud`.`deleteat` IS NULL LIMIT 1
g.Model("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid").Where("u.uid", 10).One()

Unscoped忽略时间特性

Unscoped​用于在链式操作中忽略自动时间更新特性,例如上面的示例,加上Unscoped方法后:

// SELECT * FROM `user` WHERE uid>1
g.Model("user").Unscoped().Where("uid>?", 1).All()

// SELECT * FROM `user` AS `u` LEFT JOIN `user_detail` AS `ud` ON (ud.uid=u.uid) WHERE u.uid=10 LIMIT 1
g.Model("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid").Where("u.uid", 10).Unscoped().One()

以上内容来源自官方文档:https://goframe.org/pages/viewpage.action?pageId=1114139

软删除和物理删除的区别

比如通过is_delete字段标记,默认为0,删除时设置为1

或者和视频内容一样,使用deleted_at字段标记删除的时间,默认为null

如何优雅的实现软删除

如果你详细看完了ORM链式操作-时间维护这部分内容,想必心中一定有了答案。

结合商业项目需求,有哪些容易踩的坑?

一定要结合实际情况决定使用物理删除还是软删除,下面的例子抛转引玉:

1. 比如管理后台删除轮播图这种操作建议使用软删除。因为可能出现误操作的情况,软删除可以及时找回;而且轮播图的数据往往不多,冗余保存也是没有问题的。

2. 再比如用户移除收藏文章的记录,建议物理删除。原因是收藏文章,取消收藏这类操作比较随意,没有任何风险。再者这类数据量比较庞大,软删除没有意义,反而会增加收藏操作的逻辑压力和DB压力。

本文转载自微信公众号「 程序员升级打怪之旅」,作者「王中阳Go」,可以通过以下二维码关注。

转载本文请联系「 程序员升级打怪之旅」公众号。


来源:程序员升级打怪之旅内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯