文章目录
  1. 1. 场景
  2. 2. 如何使用

golang是强类型语言,在赋值和解析过程中需要先定义好数据类型,否在会报类型错误,下面总结在处理数据库表时遇到字段为空或零值的情况

场景

假如存在如下没有指定not null的场合

1
2
3
4
5
CREATE TABLE "users" (
"id" serial not null primary key,
"name" text,
"age" integer
)

gorpinsert插入场合,可以直接赋零值即可,很方便.

1
2
3
4
5
6
dbmap.Insert(
&User{Name: "John", Age: 0}, // insert into "users" ("id","name","age") values (default,$1,$2) returning Id; [1:"John" 2:0]
&User{Name: "John"}, // insert into "users" ("id","name","age") values (default,$1,$2) returning Id; [1:"John" 2:0]
&User{Name: "", Age: 8}, // insert into "users" ("id","name","age") values (default,$1,$2) returning Id; [1:"" 2:8]
&User{Age: 30}, // insert into "users" ("id","name","age") values (default,$1,$2) returning Id; [1:"" 2:30]
)

在使用golang中零值与空值和NULL是不同的数据类型和值,需要加以判断,在数据库表中的NULL值字段可以用database/sql数据包中提供的sql.NullStringsql.NullBool等值类型进行判断后加以使用.

如何使用

可能存在NULL值的数据类型可以使用sql.NullStringsql.NullBool等来指定其类型.

1
2
3
4
5
type User struct{
Id int `db:id`
Name sql.NullString `db:name`
Age sql.NullInt64 `db:age`
}

其中sql.NullString,它的结构如下:
1
2
3
4
type NullString struct {
String string
Valid bool // Valid is true if String is not NULL
}

借助.sql.NullString这样的结构体就可以在insert时,通过设置Valid的值为fasle就可以表示此值为null值,这样在读取时如果为false就可以肯定此值为默认的空值了,具体操作如下:
1
2
3
4
5
6
7
8
9
10
dbmap.Insert(
&User{
Name: sql.NullString{"Mike", true},
Age: sql.NullInt64{0, true},
}, // insert into "users" ("id","name","age") values (default,$1,$2) returning Id; [1:"Mike" 2:0]
&User{
Name: sql.NullString{"", false},
Age: sql.NullInt64{30, true},
}, // insert into "users" ("id","name","age") values (default,$1,$2) returning Id; [1:<nil> 2:30]
)

读取数据时,可以根据valid的值判断是否为设置的零值还是未被赋值操作.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
dbmap.Insert(
&User{Name: sql.NullString{"Mike", true}, Age: sql.NullInt64{0, true}},
&User{Name: sql.NullString{"John", true}, Age: sql.NullInt64{0, false}},
&User{Name: sql.NullString{"John", true}, Age: sql.NullInt64{8, true}},
&User{Name: sql.NullString{"", false}, Age: sql.NullInt64{30, true}},
)

users := []User{}
_, err := dbmap.Select(&users, "select * from users")
if err != nil {
log.Fatal(err)
}
for _, user := range users {
spew.Dump(user)
}
/*
(main.User) {
Id: (int) 1,
Name: (sql.NullString) {
String: (string) (len=4) "Mike",
Valid: (bool) true
},
Age: (sql.NullInt64) {
Int64: (int64) 0,
Valid: (bool) true
}
}
(main.User) {
Id: (int) 2,
Name: (sql.NullString) {
String: (string) (len=4) "John",
Valid: (bool) true
},
Age: (sql.NullInt64) {
Int64: (int64) 0,
Valid: (bool) false
}
}
(main.User) {
Id: (int) 3,
Name: (sql.NullString) {
String: (string) (len=4) "John",
Valid: (bool) true
},
Age: (sql.NullInt64) {
Int64: (int64) 8,
Valid: (bool) true
}
}
(main.User) {
Id: (int) 4,
Name: (sql.NullString) {
String: (string) "",
Valid: (bool) false
},
Age: (sql.NullInt64) {
Int64: (int64) 30,
Valid: (bool) true
}
}
*/

在单次查询中根据valid的值作相应的零值判断处理, 方法如下:
1
2
3
4
5
6
7
8
var s NullString
err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
...
if s.Valid {
// use s.String
} else {
// NULL value
}

作者署名:朴实的一线攻城狮
本文标题:golang处理数据表中字段为空或NULL的情况
本文出处:http://researchlab.github.io/2016/11/23/go-dealwith-database-nullvalue/
版权声明:本文由Lee Hong创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处, 否则保留追究法律责任的权利。

@一线攻城狮

关注微信公众号 @一线攻城狮

总访问:
总访客: