go-xorm / xorm

Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm
BSD 3-Clause "New" or "Revised" License
6.67k stars 757 forks source link

model定义指针类型, 插入的时候报错 #1161

Closed axetroy closed 5 years ago

axetroy commented 5 years ago
package model

import (
    "time"
)

type UserStatus int32

const (
    UserStatusBanned      UserStatus = -100 // 账号被禁用
    UserStatusInactivated UserStatus = -1   // 账号未激活
    UserStatusInit        UserStatus = 0    // 初始化状态
)

type User struct {
    Id        int64      `xorm:"pk notnull unique" json:"id"`
    Username  string     `xorm:"notnull unique" json:"username"`
    Password  string     `xorm:"notnull varchar(36)" json:"password"`
    Nickname  *string    `xorm:"null varchar(36)" json:"nickname"`
    Phone     *string    `xorm:"null varchar(16)" json:"phone"`
    Email     *string    `xorm:"null varchar(36)" json:"email"`
    Status    UserStatus `xorm:"notnull" json:"status"`
    Role      string     `xorm:"notnull varchar(36)" json:"role"`
    Avatar    string     `xorm:"notnull varchar(36)" json:"avatar"`
    Level     int32      `xorm:"default(1)" json:"level"`
    CreatedAt time.Time  `xorm:"created" json:"created_at"`
    UpdatedAt time.Time  `xorm:"updated" json:"updated_at"`
    DeletedAt time.Time  `xorm:"deleted" json:"deleted_at"`
    Version   int32      `xorm:"version" json:"version"`
}

引用指针类型是希望, 当为nil时,数据库能写入 null

结果发现在 insert 的时候

Nickname Email Phone 赋值 nil 则报错

reflect: NumField of non-struct type
/usr/local/go/src/runtime/panic.go:513 (0x102d818)
    gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/log/log.go:326 (0x1242eff)
    Panic: panic(s)
/Users/axetroy/go/src/gitlab.com/axetroy/server/controller/auth/main.go:61 (0x176c13a)
    SignUp.func1: log.Panic(err)
/usr/local/go/src/runtime/asm_amd64.s:522 (0x105a6ea)
    call32: CALLFN(·call32, 32)
/usr/local/go/src/runtime/panic.go:513 (0x102d818)
    gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/reflect/type.go:984 (0x10801cd)
    (*rtype).NumField: panic("reflect: NumField of non-struct type")
/Users/axetroy/go/src/github.com/go-xorm/xorm/engine.go:891 (0x15da6af)
    (*Engine).mapType: for i := 0; i < t.NumField(); i++ {
/Users/axetroy/go/src/github.com/go-xorm/xorm/engine.go:817 (0x15d9c88)
    (*Engine).autoMapType: table, err = engine.mapType(v)
/Users/axetroy/go/src/github.com/go-xorm/xorm/statement.go:218 (0x1621978)
    (*Statement).setRefBean: statement.RefTable, err = statement.Engine.autoMapType(rValue(bean))
/Users/axetroy/go/src/github.com/go-xorm/xorm/session_insert.go:289 (0x160c681)
    (*Session).innerInsert: if err := session.statement.setRefBean(bean); err != nil {
/Users/axetroy/go/src/github.com/go-xorm/xorm/session_insert.go:48 (0x1608ccb)
    (*Session).Insert: cnt, err := session.innerInsert(bean)
/Users/axetroy/go/src/gitlab.com/axetroy/server/controller/auth/main.go:176 (0x176b549)
    SignUp: if _, err = session.Insert(&user); err != nil {
/Users/axetroy/go/src/github.com/gin-gonic/gin/context.go:108 (0x1564282)
    (*Context).Next: c.handlers[c.index](c)
/Users/axetroy/go/src/github.com/gin-gonic/gin/recovery.go:47 (0x1574e39)
    RecoveryWithWriter.func1: c.Next()
/Users/axetroy/go/src/github.com/gin-gonic/gin/context.go:108 (0x1564282)
    (*Context).Next: c.handlers[c.index](c)
/Users/axetroy/go/src/github.com/gin-gonic/gin/logger.go:83 (0x1574141)
    LoggerWithWriter.func1: c.Next()
/Users/axetroy/go/src/github.com/gin-gonic/gin/context.go:108 (0x1564282)
    (*Context).Next: c.handlers[c.index](c)
/Users/axetroy/go/src/github.com/gin-gonic/gin/recovery.go:47 (0x1574e39)
    RecoveryWithWriter.func1: c.Next()
/Users/axetroy/go/src/github.com/gin-gonic/gin/context.go:108 (0x1564282)
    (*Context).Next: c.handlers[c.index](c)
/Users/axetroy/go/src/github.com/gin-gonic/gin/logger.go:83 (0x1574141)
    LoggerWithWriter.func1: c.Next()
/Users/axetroy/go/src/github.com/gin-gonic/gin/context.go:108 (0x1564282)
    (*Context).Next: c.handlers[c.index](c)
/Users/axetroy/go/src/github.com/gin-gonic/gin/gin.go:359 (0x156c4ca)
    (*Engine).handleHTTPRequest: c.Next()
/Users/axetroy/go/src/github.com/gin-gonic/gin/gin.go:326 (0x156bcf1)
    (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2741 (0x12baa7a)
    serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1847 (0x12b6cd5)
    (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:1333 (0x105c3e0)
    goexit: BYTE    $0x90   // NOP

不用指针是不报错了,可是不能写入null类型了.

lunny commented 5 years ago

再插入时使用Nullable(cols...)可以插入null

axetroy commented 5 years ago

非常感谢,已解决🙏