我想使用Go为现有数据库制作一个API,该数据库广泛使用null值。Go将不会扫描null并将其转换为空字符串(或等价物),因此我需要实现一个解决方法。
我发现的解决方法让我感到不满意。实际上,我因为这个问题而寻找了一种动态语言,但Go具有某些吸引力,如果可能的话,我想坚持使用它。以下是未能令人满意的解决方法:
- 在数据库中不使用null值。这不可行,因为数据库是预先存在的,我无法干涉其结构。数据库比我的应用程序更重要,而不是相反。
- 在sql查询中,在数据到达我的应用程序之前,使用COALESCE、ISNULL等将null值转换为空字符串(或等效值)。这不可行,因为有很多字段和表。除了一些明显的字段(主键、姓氏)之外,我不确定哪些字段可以被依赖于不给我null值,所以我会在所有地方防御性地混淆我的sql查询。
- 使用sql.NullString、sql.NullInt64、sql.NullFloat64等将null值转换为空字符串(或等效值)作为中间步骤,然后将其安置到目标类型中。这与上述问题相同,只是我混淆了我的Go代码而不是我的sql查询。
- 使用*指针和[]byte的组合,将每个项目扫描到内存位置中而不将其提交给特定类型(除了[]byte),然后以某种方式处理原始数据。但是,为了对数据进行有意义的处理,您必须将其转换为更有用的内容,然后你又回到了sql.Nullstring或if x==nil{handle it},这在任何需要处理的字段的情况下都会逐个发生。因此,我们再次看到杂乱无章、混乱、容易出错的代码,并且我总是在重复自己,而不是在编码时DRY。
编写自己的辅助包来将所有空字符串转换为“”,所有空整数转换为0,所有空浮点数转换为0.00,所有空布尔值转换为false等,然后将其作为扫描 SQL 驱动程序的一部分,得到常规的字符串、整数、浮点数和布尔值。
不幸的是,如果 6 是解决方案,那我没有专业知识。我怀疑解决方案可能涉及像“如果要扫描的项的预期类型是字符串,则将其作为 sql.NullString 并从中提取空字符串。但如果要扫描的项是 int,则将其作为 NullInt64,并从中获得零。但如果...(等等)”。
还有什么我漏掉了吗?谢谢。
value int
和valid bool
,如sql.NullString
)或每行/记录一个标志字段来记录有效状态。这根本不是可以通过魔术代码轻松解决的问题。 - Dave CisNil
助手来简化此过程。您也可以使用具有类型的null
零值的其他语言。 - elithrar