表设计CREATE TABLE user ( id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID’, name varchar(64) NOT NULL DEFAULT ’’ COMMENT ‘用户名’, age int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘年龄’, birthday datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘生日’, email varchar(128) NOT NULL DEFAULT ’’ COMMENT ’email’, credit_card_id int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘信用卡ID’, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’, deleted_at datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘删除时间’, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘用户表’;CREATE TABLE credit_card ( id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID’, number varchar(64) NOT NULL DEFAULT ’’ COMMENT ‘卡号’, user_id int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘用户ID’, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’, deleted_at datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘删除时间’, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘信用卡表’;CREATE TABLE phone ( id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID’, number varchar(64) NOT NULL DEFAULT ’’ COMMENT ‘手机号’, user_id int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘用户ID’, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’, deleted_at datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘删除时间’, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘手机号表’;CREATE TABLE language ( id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID’, name varchar(64) NOT NULL DEFAULT ’’ COMMENT ‘语言名称’, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’, deleted_at datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘删除时间’, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘语言表’;CREATE TABLE user_language ( id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID’, user_id int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘用户ID’, language_id int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘语言ID’, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’, deleted_at datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘删除时间’, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘用户语言关联表’;模型flame/gorm/model/user.gopackage modelimport ( “github.com/jinzhu/gorm” “time”)type User struct { gorm.Model Name string Age uint Birthday *time.Time //数据库字段值可以为NULL 时得使用指针,否则可以不用指针 Email string CreditCard *CreditCard //避免循环嵌套,使用指针形式 //has one 模型 //不填foreignkey,默认就是【此字段type】【CreditCard】+primarykey【ID】 为【CreditCardID】 //不填association_foreignkey,默认就是【此字段type】【User】的 primarykey【ID】, //即gorm:"foreignkey:CreditCardID;association_foreignkey:ID" CreditCardID uint //为foreignkey,在本struct内 ,指向拥有哪个信用卡 //foreignkey【CreditCard】.【CreditCardID】———————>association_foreignkey【CreditCard】.【ID】 Phones []Phone gorm:"foreignkey:UserID" //has many 模型 必须要配置foreignkey //不填association_foreignkey,默认就是【此struct】【User】的 primarykey【ID】, //即gorm:"foreignkey:UserID;association_foreignkey:ID" //association_foreignkey【User】.【ID】———————>foreignkey【Phone】.【UserID】 Languages []Language gorm:"many2many:user_language;" //many to many 模型 必须要配置many2many //关联表为user_language //不填foreignkey,默认就是【此struct】【User】的 primarykey【ID】 //不填association_foreignkey,默认就是【此字段type】【Language】的 primarykey【ID】 //不填jointable_foreignkey,默认就是【此struct】【User】+primarykey【ID】 为【UserID】 转换成【user_id】 //不填association_jointable_foreignkey,默认就是【此字段type】【Language】+primarykey【ID】 为【LanguageID】 转换成【language_id】 //foreignkey【User】.【ID】———————>jointable_foreignkey【user_language】.【user_id】 //association_jointable_foreignkey【user_language】.【language_id】———————>不填association_foreignkey【Language】.【I】 //多对多 存在循环时使用指针,否则可以不用指针,避免循环嵌套}flame/gorm/model/creditCard.gopackage modelimport ( “github.com/jinzhu/gorm”)type CreditCard struct { gorm.Model Number string User *User //避免循环嵌套,使用指针形式 //belong to模型 //不填foreignkey,默认就是【此字段type】【User】+primarykey【ID】 为【UserID】 //不填association_foreignkey,默认就是此字段type【User】的 primarykey【ID】, //即gorm:"foreignkey:UserID;association_foreignkey:ID" UserID int //为foreignkey, 在本struct内 ,指向归属哪个User //foreignkey【CreditCard】.【UserID】———————>association_foreignkey【User】.【ID】}flame/gorm/model/phone.gopackage modelimport ( “github.com/jinzhu/gorm”)type Phone struct { gorm.Model Number string User User //belong to模型 //不填foreignkey,默认就是此字段type【User】+primarykey【ID】 为【UserID】 //不填association_foreignkey,默认就是此字段type【User】的 primarykey【ID】, //即gorm:"foreignkey:UserID;association_foreignkey:ID" UserID int //为foreignkey, 在本struct内 ,指向归属哪个User //foreignkey【CreditCard】.【UserID】———————>association_foreignkey【User】.【ID】}flame/gorm/model/language.gopackage modelimport ( “github.com/jinzhu/gorm”)type Language struct { gorm.Model Name string}repositoryflame/gorm/repository/User.gopackage repositoryimport ( “errors” “github.com/jinzhu/gorm” “flame/gorm/model”)type UserRepository interface { GetUserById(id int) (user model.User, err error)}func NewUserRepository(db *gorm.DB) UserRepository { return &userDBRepository{db: db}}type userDBRepository struct { db *gorm.DB}func(this *userDBRepository) GetUserById(id int)(user model.User, err error){ err = this.db.Where(“id = ?”, id).First(&user).Error if err != nil { return model.User{}, errors.New(“查询失败”) } return user, nil}dbinstanceflame/gorm/dbinstance/mysql.gopackage dbinstanceimport ( “fmt” “os” “log” “sync” “github.com/jinzhu/gorm” _ “github.com/jinzhu/gorm/dialects/mysql”)var mysqlManager *MysqlManagervar mysqlOnce sync.Oncefunc GetMysqlInstance() *MysqlManager{ mysqlOnce.Do(func(){ mysqlManager=new(MysqlManager) mysqlManager.init() }) return mysqlManager}type MysqlManager struct { DB *gorm.DB ErrorMsg error}func (this *MysqlManager) init() (*gorm.DB,error) { this.DB, this.ErrorMsg = gorm.Open(“mysql”, “<user>:<password>@tcp(<host>:<port>)/<db>?charset=utf8mb4&parseTime=True&loc=Local”) fmt.Println(this.ErrorMsg) if this.ErrorMsg != nil { log.Fatal(this.ErrorMsg) } else { this.DB.SingularTable(true)//表名为单数版 this.DB.LogMode(true) //输出日志 this.DB.SetLogger(log.New(os.Stdout, “\r\n”, 0))//输出到控制台 } return this.DB,this.ErrorMsg}func (this *MysqlManager) Destroy(){ this.DB.Close()}main 测试flame/gorm/main.gopackage mainimport ( “fmt” “flame/gorm/dbinstance” “flame/gorm/repository”)func main(){ mysqlManager:=dbinstance.GetMysqlInstance() defer mysqlManager.Destroy() db:=mysqlManager.DB userDBRepository:=repository.NewUserRepository(db) user,err:=userDBRepository.GetUserById(1) fmt.Println(user) fmt.Println(err)}运行得到输出<nil>sql/home/flame/go/src/flame/gorm/repository/User.go:243.526054msSELECT * FROM user WHERE user.deleted_at IS NULL AND ((id = ?)) ORDER BY user.id ASC LIMIT 1[1] 0{{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 0 <nil> <nil> 0 [] []}查询失败由于gorm 判断带有deleted_at 字段就会根据这个值是否NULL来判断是否删除,而我数据库字段设计是deleted_at datetime NOT NULL DEFAULT ‘1000-01-01 00:00:00’ COMMENT ‘删除时间’,有默认值,所以获取不到结果