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.gomysql
package model import ( "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.gogit
package model import ( "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.gogithub
package model import ( "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.gosql
package model import ( "github.com/jinzhu/gorm" ) type Language struct { gorm.Model Name string }
flame/gorm/repository/User.go數據庫
package repository import ( "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 }
flame/gorm/dbinstance/mysql.gotcp
package dbinstance import ( "fmt" "os" "log" "sync" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) var mysqlManager *MysqlManager var mysqlOnce sync.Once func 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() }
flame/gorm/main.go測試
package main import ( "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) }
運行獲得輸出ui
<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來判斷是否刪除,
而我數據庫字段設計是this
`deleted_at` datetime NOT NULL DEFAULT '1000-01-01 00:00:00' COMMENT '刪除時間',
有默認值,因此獲取不到結果設計