链接:https://gorm.io/zh_CN/docs/connecting_to_the_database.html
快速入门



使用gorm之前必须要建立一个数据库。gorm只能操作表。
导入gorm包的时候要导入mysql包,因为MySQL包导入时init函数自动运行驱动。
package mainimport ("database/sql""log""os""time""gorm.io/driver/mysql"//源码的init函数会执行MySQL驱动"gorm.io/gorm""gorm.io/gorm/logger")type Product struct {gorm.ModelCode sql.NullStringPrice uint}func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"//设置全局的logger,这个logger在我们执行每个sql语句的时候会打印每一行sql//sql才是最重要的,本着这个原则我尽量的给大家看到每个api背后的sql语句是什么newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式,提前建立数据库gorm_testdb, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}//定义一个表结构, 将表结构直接生成对应的表 - migrations// 迁移 schema_ = db.AutoMigrate(&Product{}) //此处应该有sql语句// 新增db.Create(&Product{Code: sql.NullString{"D42", true}, Price: 100})// Readvar product Productdb.First(&product, 1) // 根据整形主键查找db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录// Update - 将 product 的 price 更新为 200db.Model(&product).Update("Price", 200)// Update - 更新多个字段db.Model(&product).Updates(Product{Price: 200, Code:sql.NullString{"", true}}) // 仅更新非零值字段//如果我们去更新一个product 只设置了price:200//db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})// Delete - 删除 product, 并没有执行delete语句,逻辑删除db.Delete(&product, 1)}
没放logger之前
package mainimport ("log""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")type User struct {UserID uint `gorm:"primarykey"`Name string `gorm:"column:user_name;type:varchar(50);index:idx_user_name;unique;default:'bobby'"`}func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}_ = db.AutoMigrate(&User{}) //此处应该有sql语句db.Create(&User{})}
通过creat插入记录
package mainimport ("database/sql""fmt""log""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")type User struct {ID uintName stringEmail *stringAge uint8Birthday *time.TimeMemberNumber sql.NullStringActivedAt sql.NullTimeCreatedAt time.TimeUpdatedAt time.Time}func main() {a := []int{1,2,3}b := a[:]// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}_ = db.AutoMigrate(&User{}) //此处应该有sql语句user := User{Name : "bobby2",}fmt.Println(user.ID)result := db.Create(&user)fmt.Println(user.ID) // 返回插入数据的主键fmt.Println(result.Error) // 返回 errorfmt.Println(result.RowsAffected) // 返回插入记录的条数//db.Model(&User{ID:1}).Update("Name", "")//updates语句不会更新零值,但是update语句会更新//empty := ""//db.Model(&User{ID:1}).Updates(User{Email: &empty})//解决仅更新非零值字段的方法有两种/*1. 将string 设置为 *string2. 使用sql的NULLxxx来解决*/}
package mainimport ("database/sql""fmt""log""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")type User struct {ID uintName stringEmail *stringAge uint8Birthday *time.TimeMemberNumber sql.NullStringActivedAt sql.NullTimeCreatedAt time.TimeUpdatedAt time.Time}func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}//单一的 SQL 语句var users = []User{{Name: "bobby1"}, {Name: "bobby2"}, {Name: "bobby3"}}//db.Create(&users)//为什么不一次性提交所有的 还要分批次,因为sql语句有长度限制db.CreateInBatches(users, 10000)//这里的10000指的是一次提交10000个sql语句for _, user := range users {fmt.Println(user.ID) // 1,2,3}db.Model(&User{}).Create(map[string]interface{}{"Name": "jinzhu", "Age": 18,})}


package mainimport ("database/sql""fmt""log""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")type User struct {ID uintName stringEmail *stringAge uint8Birthday *time.TimeMemberNumber sql.NullStringActivedAt sql.NullTimeCreatedAt time.TimeUpdatedAt time.Time}func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}//通过first查询单个数据, 获取第一条记录(主键升序)//var user User//db.First(&user)//通过主键查询//我们不能给user赋值//result := db.First(&user, []int{1,2,3})//if errors.Is(result.Error, gorm.ErrRecordNotFound){// fmt.Println("未找到")//}//fmt.Println(user.ID)//检索全部对象var users []Userresult := db.Find(&users)fmt.Println("总共记录:", result.RowsAffected)for _, user := range users{fmt.Println(user.ID)}}


package mainimport ("database/sql""fmt""log""math/rand""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")type User struct {ID uintMyName string `gorm:"column:name"`Email *stringAge uint8Birthday *time.TimeMemberNumber sql.NullStringActivedAt sql.NullTimeCreatedAt time.TimeUpdatedAt time.Time}type BaseModel struct {ID int32 `gorm:"primarykey;type:int" json:"id"` //为什么使用int32, bigintCreatedAt time.Time `gorm:"column:add_time" json:"-"`UpdatedAt time.Time `gorm:"column:update_time" json:"-"`DeletedAt gorm.DeletedAt `json:"-"`IsDeleted bool `json:"-"`}type OrderInfo struct{BaseModelUser int32 `gorm:"type:int;index"`OrderSn string `gorm:"type:varchar(30);index"` //订单号,我们平台自己生成的订单号PayType string `gorm:"type:varchar(20) comment 'alipay(支付宝), wechat(微信)'"`//status大家可以考虑使用iota来做Status string `gorm:"type:varchar(20) comment 'PAYING(待支付), TRADE_SUCCESS(成功), TRADE_CLOSED(超时关闭), WAIT_BUYER_PAY(交易创建), TRADE_FINISHED(交易结束)'"`TradeNo string `gorm:"type:varchar(100) comment '交易号'"` //交易号就是支付宝的订单号 查账OrderMount float32PayTime *time.Time `gorm:"type:datetime"`Address string `gorm:"type:varchar(100)"`SignerName string `gorm:"type:varchar(20)"`SingerMobile string `gorm:"type:varchar(11)"`Post string `gorm:"type:varchar(20)"`}type OrderGoods struct{BaseModelOrder int32 `gorm:"type:int;index"`Goods int32 `gorm:"type:int;index"`//把商品的信息保存下来了 , 字段冗余, 高并发系统中我们一般都不会遵循三范式 做镜像 记录GoodsName string `gorm:"type:varchar(100);index"`GoodsImage string `gorm:"type:varchar(200)"`GoodsPrice float32Nums int32 `gorm:"type:int"`}func GenerateOrderSn(userId int32) string{//订单号的生成规则/*年月日时分秒+用户id+2位随机数*/now := time.Now()rand.Seed(time.Now().UnixNano())orderSn := fmt.Sprintf("%d%d%d%d%d%d%d%d",now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Nanosecond(),userId, rand.Intn(90)+10,)return orderSn}func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}//通过where查询//var user User//var users []User//db.Where("name = ?", "bobby").First(&user)//db.Where(&User{MyName:"bobby"}).First(&user)//db.Where(&User{MyName:"bobby1", Age: 0}).Find(&users)//db.Where(map[string]interface{}{"name": "bobby", "age":0}).Find(&users)//for _, user := range users{// fmt.Println(user.ID)//}_ = db.AutoMigrate(OrderInfo{}, OrderGoods{})tx := db.Begin()order := OrderInfo{OrderSn: GenerateOrderSn(1),OrderMount: 44.2,Address: "北京市",SignerName: "bobby",SingerMobile: "18787878787",Post: "请尽快发货",}if result := tx.Save(&order); result.RowsAffected == 0 {tx.Rollback()fmt.Println("创建订单失败")}var orderGoods []*OrderGoodsorderGoods = append(orderGoods, &OrderGoods{Order: order.ID,Goods: 421,GoodsName: "烟台红富士苹果12个 净重2.6kg以上 单果190-240g 新生鲜水果",GoodsImage: "https://py-go.oss-cn-beijing.aliyuncs.com/goods_images/df392d01993cdab9de740fe17798bda1",GoodsPrice: 44.9,Nums: 1,})for _, orderGood := range orderGoods {orderGood.Order = order.ID}//批量插入orderGoodsif result := tx.CreateInBatches(orderGoods, 100); result.RowsAffected == 0 {tx.Rollback()fmt.Println("创建订单失败")}tx.Commit()//查询方式条件有三种 1. string 2. struct 3. map}





package mainimport ("log""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")// `User` 属于 `Company`,`CompanyID` 是外键type User struct {gorm.ModelName stringCompanyID int //数据库中存储的字段company_idCompany Company}type Company struct {ID intName string}func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if err != nil {panic(err)}//db.AutoMigrate(&User{}) //新建了user表和company表,并设置了外键//db.Create(&User{// Name: "bobby",// Company: Company{// Name:"慕课网",// },//})db.Create(&User{Name: "bobby2",Company: Company{ID:1,},})}
package mainimport ("database/sql""gorm.io/gorm/schema""log""os""time""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger")type Language struct {gorm.ModelName stringAddTime sql.NullTime //每个记录创建的时候自动加上当前时间加入到AddTime中}//func (l *Language) BeforeCreate(tx *gorm.DB) (err error){// l.AddTime = time.Now()// return//}//在gorm中可以通过给某一个struct添加TableName方法来自定义表名func (Language) TableName() string{return "my_language"}/*1. 我们自己定义表名是什么2. 统一的给所有的表名加上一个前缀*/func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold: time.Second, // 慢 SQL 阈值LogLevel: logger.Info, // Log levelColorful: true, // 禁用彩色打印},)// 全局模式//NamingStrategy和Tablename不能同时配置,db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{NamingStrategy:schema.NamingStrategy{//配置表名前缀TablePrefix: "mxshop_",},Logger: newLogger,})if err != nil {panic(err)}db.AutoMigrate(&Language{})db.Create(&Language{Name:"python",})}
