问题
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log"
"os"
"time"
)
type Product struct {
gorm.Model
Code string
Price uint
}
func main() {
// 连接对应的数据库
dsn := "root:root@tcp(192.168.193.128:3306)/grom_test?charset=utf8mb4&parseTime=True&loc=Local"
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer(日志输出的目标,前缀和日志包含的内容——译者注)
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: true, // 使用用彩色打印
},
)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger})
if err != nil {
panic(err)
}
db.Create(&Product{Code: "DDD",Price: 20})
db.Updates(&Product{Code: "",Price: 0})
}
日志:
INSERT INTO `products` (`created_at`,`updated_at`,`deleted_at`,`code`,`price`) VALUES ('2022-05-26 13:51:01.517','2022-05-26 13:51:01.517',NULL,'DDD',20)
UPDATE `products` SET `updated_at`='2022-05-26 13:52:01.06' WHERE `products`.`deleted_at` IS NULL
我们再执行修改操作时,将Code设置为"“将Price设置成0;但是再执行SQL时没有将这两个字段进行修改.表中的值还是原值.是因为这里用到的更新仅更新非零值字段;”"就是string的零值.0就是uint的零值;所以不做更新
解决方案
使用sql.NullXxx
将code的类型改为sql.NullString;price的类型sql.NullInt32
package main
import (
"database/sql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log"
"os"
"time"
)
type Product struct {
gorm.Model
Code sql.NullString
Price sql.NullInt32
}
func main() {
// 连接对应的数据库
dsn := "root:root@tcp(192.168.193.128:3306)/grom_test?charset=utf8mb4&parseTime=True&loc=Local"
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer(日志输出的目标,前缀和日志包含的内容——译者注)
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: true, // 使用用彩色打印
},
)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger})
if err != nil {
panic(err)
}
var p Product
db.Model(&p).Where("code = ?","DDD").
Updates(Product{Code: sql.NullString{String: "", Valid: true}, Price: sql.NullInt32{Int32: 0, Valid: true}})
}
日志:
UPDATE `products` SET `updated_at`='2022-05-26 14:28:51.882',`code`='',`price`=0 WHERE code = 'DDD' AND `products`.`deleted_at` IS NULL
如果需要更新非零值字段的话,就需要把类型设置为sql.NullString;常用类型只要是有零值的类型,再sql包下都有对零值的处理;
使用指针
package main
import (
"database/sql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log"
"os"
"time"
)
type Product struct {
gorm.Model
Code *string
Price sql.NullInt32
}
func main() {
// 连接对应的数据库
dsn := "root:root@tcp(192.168.193.128:3306)/grom_test?charset=utf8mb4&parseTime=True&loc=Local"
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer(日志输出的目标,前缀和日志包含的内容——译者注)
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: true, // 使用用彩色打印
},
)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger})
if err != nil {
panic(err)
}
var p Product
code := ""
db.Model(&p).Where("code = ?","DDD").
Updates(Product{Code: &code, Price: sql.NullInt32{Int32: 0, Valid: true}})
}
日志:
UPDATE `products` SET `updated_at`='2022-05-26 15:28:31.906',`code`='',`price`=0 WHERE code = 'DDD' AND `products`.`deleted_at` IS NULL
使用指针同样可以对零值进行修改