1#signal SIGSEGV: segmentation violation
错误信息
vagrant@homestead:/var/go/src/gin$ go run main.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb0 pc=0x9cf1a6]
goroutine 1 [running]:
github.com/jinzhu/gorm.(*DB).clone(0x0, 0x40dd08)
/var/go/pkg/mod/github.com/jinzhu/gorm@v1.9.10/main.go:821 +0x26
github.com/jinzhu/gorm.(*DB).Unscoped(...)
/var/go/pkg/mod/github.com/jinzhu/gorm@v1.9.10/main.go:312
github.com/jinzhu/gorm.(*DB).AutoMigrate(0x0, 0xc000193f18, 0x1, 0x1, 0x1)
/var/go/pkg/mod/github.com/jinzhu/gorm@v1.9.10/main.go:655 +0x30
github.com/tqsq2005/go-newbird/gin/models.migration(...)
/var/go/src/gin/models/models.go:44
github.com/tqsq2005/go-newbird/gin/models.Setup()
/var/go/src/gin/models/models.go:30 +0x2c1
main.init.0()
/var/go/src/gin/main.go:12 +0x25
exit status 2
错误定位
package models
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/tqsq2005/go-newbird/gin/pkg/setting"
"log"
"time"
)
var db *gorm.DB
func Setup() {
var err error
db, err := gorm.Open(setting.DatabaseSetting.Type, fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
setting.DatabaseSetting.User,
setting.DatabaseSetting.Password,
setting.DatabaseSetting.Host,
setting.DatabaseSetting.Name))
if err != nil {
log.Fatalf("models.Setup err:%v", err)
}
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
return setting.DatabaseSetting.TablePrefix + defaultTableName
}
migration()
// 关闭复数表名,如果设置为true,`User`表的表名就会是`user`,而不是`users`
//db.SingularTable(true)
// SetMaxIdleCons 设置连接池中的最大闲置连接数。
db.DB().SetMaxIdleConns(10)
// SetMaxOpenCons 设置数据库的最大连接数量
db.DB().SetMaxOpenConns(100)
// SetConnMaxLifetiment 设置连接的最大可复用时间。
db.DB().SetConnMaxLifetime(time.Hour)
}
func migration() {
db.AutoMigrate(&User{}, &Article{})
}
func CloseDB() {
defer db.Close()
}
go报的定位到migration()这边,推断出应该是db这个变量有问题,找到db赋值的地方,db, err := gorm.Open(...),这边的db因为:的操作符其实是函数内部的局部变量,而不是外面的全局变量,代码改为db, err = gorm.Open(...),错误解决!
#2定义模型中的gorm:"size:length"注释的时候size:length之间不能有空格
下面的代码生成的password和remember_token表结果是varchar
type User struct {
gorm.Model
UserName string `gorm:"type: varchar(30); not null" json:"user_name"`
Email string `gorm:"type: varchar(50); unique_index; not null" json:"email"`
EmailVerifiedAt *time.Time `json:"email_verified_at"`
Tel string `gorm:"type: varchar(20); unique_index; not null" json:"tel"`
Password string `gorm:"size:60; not null" json:"password"`
RememberToken string `gorm:"size:60" json:"remember_token"`
}
下面的代码生成的password和remember_token表结果是longtext,仅仅是因为size: 60;: size:和60之间有空格!
type User struct {
gorm.Model
UserName string `gorm:"type: varchar(30); not null" json:"user_name"`
Email string `gorm:"type: varchar(50); unique_index; not null" json:"email"`
EmailVerifiedAt *time.Time `json:"email_verified_at"`
Tel string `gorm:"type: varchar(20); unique_index; not null" json:"tel"`
Password string `gorm:"size: 60; not null" json:"password"`
RememberToken string `gorm:"size: 60" json:"remember_token"`
}
#其他
- 1、gorm设置varchar(100)和size:100有什么区别?
区别在于,
type后的定义将会直接作用到create table语句中,你还可以设置type:"int(11) unsigned auto_increment;",且type有最高优先级size只作用于类型为string或array或slice的字段,为string类型时判断size在0到65532之间时自动设置为varchar,大于65532时设置为longtext,否则自动设置为varbinary或longblob类型详见:dialect_mysql.go#L31(仅针对mysql)
- 2、sql.NullInt64是什么意思?
允许db中值为NULL的bigint类型
- 3、MemberNumber字段的类型是*string,和string有什么不同,什么时候使用指针类型?
*string允许为空,也就是说允许设置为NULL,string默认值是空字符串,保存时前者设置为NULL,后者为空字符串
- 4、IgnoreMe字段后面的gorm:"-" // 忽略本字段,这个**“忽略本字段”**是什么意思?
本字段不作为数据库的映射字段
- 5、
type:"int(11) unsigned auto_increment;"可以改成中间加分号吗?像这样:type:"int(11);unsigned;auto_increment;"
不行,type是有最高优先级的,直接作用到
create table语句中,加分号的话,语句错误
- 6、
unique和unique_index的区别
unique means "has to be unique value", it's an equivalent of setting a UNIQUE constraint on a database table field. unique_index means "index database on this value, which is unique", it's an equivalent of creating a unique index in the database — you can specify a name of such index and use the annotation with the same name on multiple struct fields:
// just an exampe
type Example struct {
// two people can have the same name
Name string `gorm:"primary_key;unique_index:exampleindex"`
// but usernames have to be unique
Username string `gorm:"unique;"`
// colors can be repeating too
FavoriteColor string `gorm:"unique_index:exampleindex"`
// But combinations of User + FavoriteColor have to be UNIQUE
}
- 7
- 8
- 9
- 10