初学者必须搞懂:
在 Go 中,没有null、none、NULL、None
任何类型在未初始化时都对应一个零值:布尔类型是 false ,整型是 0 ,字符串是 ""
而指针,函数,interface,slice,channel和map的零值都是 nil
结合场景,平衡利弊,做出取舍
下图是一位读者问我的问题,我翻遍了文档也没找到相关的资料,猜测应该是不支持的。
于是问了goframe作者,被明确告知:goframe不支持,并且以后也不会支持。
作者也详细解答了不支持的原因,goframe作者团队的考虑是这样的:
因为我做的项目比较多,在数据库表结构管理方面踩过坑。还是比较能接受goframe作者观点的。
migrate这种功能确实能方便开发者,但是在企业级项目中,尤其是TOB的业务,稳定是第一要务。migrate功能虽然方便,但是不够严谨,如果没有很强的规范去约束团队成员的使用,很容易出问题,出了问题就不是小问题,所以不敢用。
这也让我想起了另外一件事情:
前段时间在review代码时,发现了一个“无条件”的删除脚本在运行,心头一惊啊!这要是把数据删了可麻烦了。但是查询DB发现没有删除数据。
我详细查了官方文档,没有被删数据的原因是这样的:
goframe是一款用于企业生产级别的框架,各个模块设计严谨,工程实践的细节处理得比较好。为安全性保证、防止误操作,Update及Delete方法必须带有Where条件才能提交执行,否则将会错误返回,错误信息如:there should be WHERE condition statement for XXX operation。
好吧,感谢,真是救我狗命了,哈哈。
也正是因为自己做了很多项目,踩了很多坑,碰到了不少这种细节问题。
目前才有了“从追求开发效率”到“追求项目稳定性”的转变。
在这里也回答一下最近大家私信我的问题吧:“为什么我使用goframe框架做这个电商实战项目?”
原因很简单,我结合自己的经历,觉得GoFrame是一个适合企业级项目比较严谨的框架,能少踩坑,避免一些麻烦。虽然入门门槛是有的,但是在“工程化开发设计”的规范下,后续的维护成本还是比较低的。所以才带大家使用这个框架做电商项目的。
好了,不同的场景,不同的项目有不同的解决方案,不同的优选框架。这个问题没有标准答案,结合自己的需求去选择合适的解决方案吧。
欢迎大家找我交流,多提像这位读者一样有价值的问题,一起进步!
Fields/FieldsEx字段过滤
Fields 用于指定需要操作的表字段,包括查询字段、写入字段、更新字段等过滤;
FieldsEx 用于例外的字段指定,可用于查询字段、写入字段、更新字段等过滤;
Fields示例
假如user表有4个字段uid, nickname, passport, password。
查询字段过滤
写入字段过滤
FieldsEx示例
1.假如user表有4个字段uid, nickname, passport, password。
2.查询字段排除
3.写入字段排除
OmitEmpty空值过滤
当 map/struct 中存在空值如 nil,"",0 时,默认情况下,gdb将会将其当做正常的输入参数,因此这些参数也会被更新到数据表。OmitEmpty特性可以在将数据写入到数据库之前过滤空值数据的字段。
相关方法:
OmitEmpty方法会同时过滤Where及Data中的空值数据,而通过OmitEmptyWhere/OmitEmptyData方法可以执行特定的字段过滤。
写入/更新操作
空值会影响于写入/更新操作方法,如Insert, Replace, Update, Save操作。如以下操作(以map为例,struct同理):
针对空值情况,我们可以通过OmitEmpty方法来过滤掉这些空值。例如,以上示例可以修改为:
对于struct数据参数,我们也可以进行空值过滤。操作示例:
注意哟,批量写入/更新操作中OmitEmpty方法将会失效,因为在批量操作中,必须保证每个写入记录的字段是统一的。
关于omitempty标签与OmitEmpty方法:
针对于struct的空值过滤大家会想到omitempty的标签。该标签常用于json转换的空值过滤,也在某一些第三方的ORM库中用作struct到数据表字段的空值过滤,即当属性为空值时不做转换。
omitempty标签与OmitEmpty方法所达到的效果是一样的。在ORM操作中,我们不建议对struct使用omitempty的标签来控制字段的空值过滤,而建议使用OmitEmpty方法来做控制。因为该标签一旦加上之后便绑定到了struct上,没有办法做灵活控制;而通过OmitEmpty方法使得开发者可以选择性地、根据业务场景对struct做空值过滤,操作更加灵活。
数据查询操作
空值也会影响数据查询操作,主要是影响where条件参数。我们可以通过OmitEmpty方法过滤条件参数中的空值。
使用示例:
OmitNil空值过滤
当 map/struct 中存在空值如 nil时,默认情况下,gdb将会将其当做正常的输入参数,因此这些参数也会被更新到数据表。OmitNil特性可以在将数据写入到数据库之前过滤空值数据的字段。与OmitEmpty特性的区别在于,OmitNil只会过滤值为nil的空值字段,其他空值如"",0并不会被过滤。
相关方法:
OmitNil方法会同时过滤Where及Data中的空值数据,而通过OmitNilWhere/OmitNilData方法可以执行特定的字段过滤。
Filter字段过滤(已内置)
gdb可以自动同步数据表结构到程序缓存中(缓存不过期,直至程序重启/重新部署),并且可以过滤提交参数中不符合表结构的数据项,该特性可以使用Filter方法实现。常用于新增/删除操作中输入map/struct/[]map/[]string参数类型的场景。
使用示例,假如user表有4个字段uid, nickname, passport, password:
其中id为不存在的字段,在写入数据时将会被过滤掉,不至于被构造成写入SQL中产生执行错误。
数据库没有设计为Data方法做自动过滤,而是需要开发者调用Filter方法来手动指定过滤,目的是友好地提醒开发者可能误写/传递错误了字段名称。如果强制性的自动过滤可能会引起难以预料的业务逻辑异常,例如,由于字段名称拼写错误导致自动过滤了本来需要输入的字段,导致写入数据库的数据不完整。
从GoFrame v1.15.7版本开始,根据社区整体反馈,为提高组件易用性,filter特性被设置为默认开启,不再需要显示调用,Filter方法已被标记废弃。
本文转载自微信公众号「 程序员升级打怪之旅」,作者「王中阳Go」,可以通过以下二维码关注。
转载本文请联系「 程序员升级打怪之旅」公众号。