工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表2017年06月的文章

golang null值处理

NULL值处理

简单说就是设计数据库的时候不要出现null,处理起来非常费力。Null的type很有限,例如没有sql.NullUint64; null值没有默认零值。

for rows.Next() {     var s sql.NullString     err := rows.Scan(&s)     // check err     if s.Valid {        // use s.String     } else {        // NULL value     } }

 

https://segmentfault.com/a/1190000003036452
 
 
------------

而对于在Go中构建页面, text/template 中的很多功能不会自动判断Nullable类型,比如 {{if .Property}} ,如果 Property 属性是Nullable类型,且他是 NULL 即 Valid 属性为 false ,但是模板中的 if 还是会认为 true ,因为这个Nullable类型本身是一个值所以 if 会认为是 true,而Nullable类型本身到底是不是 NULL 根本没有意义,所以必须要写 {{if .Property.Valid}}。在输出上,也要写 {{.Property.String}} (不同Nullable类型值得属性会不一样,这里以 sql.NullString 演示)。

或者用实际代码演示这个问题:

package main  import (     "bytes"     "database/sql"     "fmt"     "text/template" )  type Test struct {     EmptyString    sql.NullString     NonEmptyString sql.NullString }  func main() {     test := &Test{}     test.EmptyString = sql.NullString{Valid: false}     test.NonEmptyString = sql.NullString{Valid: true, String: "Mgen"}     template := template.Must(template.New("test").Parse("{{if .EmptyString}}{{.NonEmptyString}}{{end}}"))     buffer := &bytes.Buffer{}     err := template.Execute(buffer, test)     if err != nil {         panic(err)     }     fmt.Print(buffer.String()) } 

这段代码会输出:

{Mgen true} 

验证了上面讲的两个问题:

  • 为 NULL 的Nullable类型会在模板 if 中直接理解成 true .
  • 输出问题,上面输出 {Mgen true} 实际上就是把 sql.NullString 的两个内部属性全部输出出来了。

Go中 NullString 类型定义:

type NullString struct {         String string         Valid  bool // Valid is true if String is not NULL } 

所以正确的模板应该这样写:

template := template.Must(template.New("test").Parse("{{if .EmptyString.Valid}}{{.NonEmptyString.String}}{{end}}")) 

总之一旦遇到数据库中的 NULL ,还是会稍微有些麻烦的,目前的解决方案可供选择:

  • 数据库中尽量不存 NULL 值,或者使用 ISNULL 或 COALESCE 对 NULL 值坐下处理。
  • JSON上对Nullable类型进行改造,模板定义上属性要针对Nullable类型的属性做判断。
  • 不需要Nullable, NULL 值转换成空值, 这是文章开头我说的愿望:joy:,目前不支持 。
 
 
http://www.tuicool.com/articles/QJZJjaQ
Records:912