链接:https://gorm.io/zh_CN/docs/connecting_to_the_database.html

快速入门

image.png
image.png
image.png
使用gorm之前必须要建立一个数据库。gorm只能操作表。
导入gorm包的时候要导入mysql包,因为MySQL包导入时init函数自动运行驱动。

  1. package main
  2. import (
  3. "database/sql"
  4. "log"
  5. "os"
  6. "time"
  7. "gorm.io/driver/mysql"//源码的init函数会执行MySQL驱动
  8. "gorm.io/gorm"
  9. "gorm.io/gorm/logger"
  10. )
  11. type Product struct {
  12. gorm.Model
  13. Code sql.NullString
  14. Price uint
  15. }
  16. func main() {
  17. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  18. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  19. //设置全局的logger,这个logger在我们执行每个sql语句的时候会打印每一行sql
  20. //sql才是最重要的,本着这个原则我尽量的给大家看到每个api背后的sql语句是什么
  21. newLogger := logger.New(
  22. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  23. logger.Config{
  24. SlowThreshold: time.Second, // 慢 SQL 阈值
  25. LogLevel: logger.Info, // Log level
  26. Colorful: true, // 禁用彩色打印
  27. },
  28. )
  29. // 全局模式,提前建立数据库gorm_test
  30. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  31. Logger: newLogger,
  32. })
  33. if err != nil {
  34. panic(err)
  35. }
  36. //定义一个表结构, 将表结构直接生成对应的表 - migrations
  37. // 迁移 schema
  38. _ = db.AutoMigrate(&Product{}) //此处应该有sql语句
  39. // 新增
  40. db.Create(&Product{Code: sql.NullString{"D42", true}, Price: 100})
  41. // Read
  42. var product Product
  43. db.First(&product, 1) // 根据整形主键查找
  44. db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录
  45. // Update - 将 product 的 price 更新为 200
  46. db.Model(&product).Update("Price", 200)
  47. // Update - 更新多个字段
  48. db.Model(&product).Updates(Product{Price: 200, Code:sql.NullString{"", true}}) // 仅更新非零值字段
  49. //如果我们去更新一个product 只设置了price:200
  50. //db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})
  51. // Delete - 删除 product, 并没有执行delete语句,逻辑删除
  52. db.Delete(&product, 1)
  53. }

没放logger之前image.png

  1. package main
  2. import (
  3. "log"
  4. "os"
  5. "time"
  6. "gorm.io/driver/mysql"
  7. "gorm.io/gorm"
  8. "gorm.io/gorm/logger"
  9. )
  10. type User struct {
  11. UserID uint `gorm:"primarykey"`
  12. Name string `gorm:"column:user_name;type:varchar(50);index:idx_user_name;unique;default:'bobby'"`
  13. }
  14. func main() {
  15. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  16. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  17. newLogger := logger.New(
  18. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  19. logger.Config{
  20. SlowThreshold: time.Second, // 慢 SQL 阈值
  21. LogLevel: logger.Info, // Log level
  22. Colorful: true, // 禁用彩色打印
  23. },
  24. )
  25. // 全局模式
  26. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  27. Logger: newLogger,
  28. })
  29. if err != nil {
  30. panic(err)
  31. }
  32. _ = db.AutoMigrate(&User{}) //此处应该有sql语句
  33. db.Create(&User{})
  34. }

通过creat插入记录

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "log"
  6. "os"
  7. "time"
  8. "gorm.io/driver/mysql"
  9. "gorm.io/gorm"
  10. "gorm.io/gorm/logger"
  11. )
  12. type User struct {
  13. ID uint
  14. Name string
  15. Email *string
  16. Age uint8
  17. Birthday *time.Time
  18. MemberNumber sql.NullString
  19. ActivedAt sql.NullTime
  20. CreatedAt time.Time
  21. UpdatedAt time.Time
  22. }
  23. func main() {
  24. a := []int{1,2,3}
  25. b := a[:]
  26. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  27. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  28. newLogger := logger.New(
  29. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  30. logger.Config{
  31. SlowThreshold: time.Second, // 慢 SQL 阈值
  32. LogLevel: logger.Info, // Log level
  33. Colorful: true, // 禁用彩色打印
  34. },
  35. )
  36. // 全局模式
  37. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  38. Logger: newLogger,
  39. })
  40. if err != nil {
  41. panic(err)
  42. }
  43. _ = db.AutoMigrate(&User{}) //此处应该有sql语句
  44. user := User{
  45. Name : "bobby2",
  46. }
  47. fmt.Println(user.ID)
  48. result := db.Create(&user)
  49. fmt.Println(user.ID) // 返回插入数据的主键
  50. fmt.Println(result.Error) // 返回 error
  51. fmt.Println(result.RowsAffected) // 返回插入记录的条数
  52. //db.Model(&User{ID:1}).Update("Name", "")
  53. //updates语句不会更新零值,但是update语句会更新
  54. //empty := ""
  55. //db.Model(&User{ID:1}).Updates(User{Email: &empty})
  56. //解决仅更新非零值字段的方法有两种
  57. /*
  58. 1. 将string 设置为 *string
  59. 2. 使用sql的NULLxxx来解决
  60. */
  61. }
  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "log"
  6. "os"
  7. "time"
  8. "gorm.io/driver/mysql"
  9. "gorm.io/gorm"
  10. "gorm.io/gorm/logger"
  11. )
  12. type User struct {
  13. ID uint
  14. Name string
  15. Email *string
  16. Age uint8
  17. Birthday *time.Time
  18. MemberNumber sql.NullString
  19. ActivedAt sql.NullTime
  20. CreatedAt time.Time
  21. UpdatedAt time.Time
  22. }
  23. func main() {
  24. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  25. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  26. newLogger := logger.New(
  27. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  28. logger.Config{
  29. SlowThreshold: time.Second, // 慢 SQL 阈值
  30. LogLevel: logger.Info, // Log level
  31. Colorful: true, // 禁用彩色打印
  32. },
  33. )
  34. // 全局模式
  35. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  36. Logger: newLogger,
  37. })
  38. if err != nil {
  39. panic(err)
  40. }
  41. //单一的 SQL 语句
  42. var users = []User{{Name: "bobby1"}, {Name: "bobby2"}, {Name: "bobby3"}}
  43. //db.Create(&users)
  44. //为什么不一次性提交所有的 还要分批次,因为sql语句有长度限制
  45. db.CreateInBatches(users, 10000)//这里的10000指的是一次提交10000个sql语句
  46. for _, user := range users {
  47. fmt.Println(user.ID) // 1,2,3
  48. }
  49. db.Model(&User{}).Create(map[string]interface{}{
  50. "Name": "jinzhu", "Age": 18,
  51. })
  52. }

image.png
image.png

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "log"
  6. "os"
  7. "time"
  8. "gorm.io/driver/mysql"
  9. "gorm.io/gorm"
  10. "gorm.io/gorm/logger"
  11. )
  12. type User struct {
  13. ID uint
  14. Name string
  15. Email *string
  16. Age uint8
  17. Birthday *time.Time
  18. MemberNumber sql.NullString
  19. ActivedAt sql.NullTime
  20. CreatedAt time.Time
  21. UpdatedAt time.Time
  22. }
  23. func main() {
  24. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  25. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  26. newLogger := logger.New(
  27. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  28. logger.Config{
  29. SlowThreshold: time.Second, // 慢 SQL 阈值
  30. LogLevel: logger.Info, // Log level
  31. Colorful: true, // 禁用彩色打印
  32. },
  33. )
  34. // 全局模式
  35. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  36. Logger: newLogger,
  37. })
  38. if err != nil {
  39. panic(err)
  40. }
  41. //通过first查询单个数据, 获取第一条记录(主键升序)
  42. //var user User
  43. //db.First(&user)
  44. //通过主键查询
  45. //我们不能给user赋值
  46. //result := db.First(&user, []int{1,2,3})
  47. //if errors.Is(result.Error, gorm.ErrRecordNotFound){
  48. // fmt.Println("未找到")
  49. //}
  50. //fmt.Println(user.ID)
  51. //检索全部对象
  52. var users []User
  53. result := db.Find(&users)
  54. fmt.Println("总共记录:", result.RowsAffected)
  55. for _, user := range users{
  56. fmt.Println(user.ID)
  57. }
  58. }

image.png
image.png

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "log"
  6. "math/rand"
  7. "os"
  8. "time"
  9. "gorm.io/driver/mysql"
  10. "gorm.io/gorm"
  11. "gorm.io/gorm/logger"
  12. )
  13. type User struct {
  14. ID uint
  15. MyName string `gorm:"column:name"`
  16. Email *string
  17. Age uint8
  18. Birthday *time.Time
  19. MemberNumber sql.NullString
  20. ActivedAt sql.NullTime
  21. CreatedAt time.Time
  22. UpdatedAt time.Time
  23. }
  24. type BaseModel struct {
  25. ID int32 `gorm:"primarykey;type:int" json:"id"` //为什么使用int32, bigint
  26. CreatedAt time.Time `gorm:"column:add_time" json:"-"`
  27. UpdatedAt time.Time `gorm:"column:update_time" json:"-"`
  28. DeletedAt gorm.DeletedAt `json:"-"`
  29. IsDeleted bool `json:"-"`
  30. }
  31. type OrderInfo struct{
  32. BaseModel
  33. User int32 `gorm:"type:int;index"`
  34. OrderSn string `gorm:"type:varchar(30);index"` //订单号,我们平台自己生成的订单号
  35. PayType string `gorm:"type:varchar(20) comment 'alipay(支付宝), wechat(微信)'"`
  36. //status大家可以考虑使用iota来做
  37. Status string `gorm:"type:varchar(20) comment 'PAYING(待支付), TRADE_SUCCESS(成功), TRADE_CLOSED(超时关闭), WAIT_BUYER_PAY(交易创建), TRADE_FINISHED(交易结束)'"`
  38. TradeNo string `gorm:"type:varchar(100) comment '交易号'"` //交易号就是支付宝的订单号 查账
  39. OrderMount float32
  40. PayTime *time.Time `gorm:"type:datetime"`
  41. Address string `gorm:"type:varchar(100)"`
  42. SignerName string `gorm:"type:varchar(20)"`
  43. SingerMobile string `gorm:"type:varchar(11)"`
  44. Post string `gorm:"type:varchar(20)"`
  45. }
  46. type OrderGoods struct{
  47. BaseModel
  48. Order int32 `gorm:"type:int;index"`
  49. Goods int32 `gorm:"type:int;index"`
  50. //把商品的信息保存下来了 , 字段冗余, 高并发系统中我们一般都不会遵循三范式 做镜像 记录
  51. GoodsName string `gorm:"type:varchar(100);index"`
  52. GoodsImage string `gorm:"type:varchar(200)"`
  53. GoodsPrice float32
  54. Nums int32 `gorm:"type:int"`
  55. }
  56. func GenerateOrderSn(userId int32) string{
  57. //订单号的生成规则
  58. /*
  59. 年月日时分秒+用户id+2位随机数
  60. */
  61. now := time.Now()
  62. rand.Seed(time.Now().UnixNano())
  63. orderSn := fmt.Sprintf("%d%d%d%d%d%d%d%d",
  64. now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Nanosecond(),
  65. userId, rand.Intn(90)+10,
  66. )
  67. return orderSn
  68. }
  69. func main() {
  70. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  71. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  72. newLogger := logger.New(
  73. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  74. logger.Config{
  75. SlowThreshold: time.Second, // 慢 SQL 阈值
  76. LogLevel: logger.Info, // Log level
  77. Colorful: true, // 禁用彩色打印
  78. },
  79. )
  80. // 全局模式
  81. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  82. Logger: newLogger,
  83. })
  84. if err != nil {
  85. panic(err)
  86. }
  87. //通过where查询
  88. //var user User
  89. //var users []User
  90. //db.Where("name = ?", "bobby").First(&user)
  91. //db.Where(&User{MyName:"bobby"}).First(&user)
  92. //db.Where(&User{MyName:"bobby1", Age: 0}).Find(&users)
  93. //db.Where(map[string]interface{}{"name": "bobby", "age":0}).Find(&users)
  94. //for _, user := range users{
  95. // fmt.Println(user.ID)
  96. //}
  97. _ = db.AutoMigrate(OrderInfo{}, OrderGoods{})
  98. tx := db.Begin()
  99. order := OrderInfo{
  100. OrderSn: GenerateOrderSn(1),
  101. OrderMount: 44.2,
  102. Address: "北京市",
  103. SignerName: "bobby",
  104. SingerMobile: "18787878787",
  105. Post: "请尽快发货",
  106. }
  107. if result := tx.Save(&order); result.RowsAffected == 0 {
  108. tx.Rollback()
  109. fmt.Println("创建订单失败")
  110. }
  111. var orderGoods []*OrderGoods
  112. orderGoods = append(orderGoods, &OrderGoods{
  113. Order: order.ID,
  114. Goods: 421,
  115. GoodsName: "烟台红富士苹果12个 净重2.6kg以上 单果190-240g 新生鲜水果",
  116. GoodsImage: "https://py-go.oss-cn-beijing.aliyuncs.com/goods_images/df392d01993cdab9de740fe17798bda1",
  117. GoodsPrice: 44.9,
  118. Nums: 1,
  119. })
  120. for _, orderGood := range orderGoods {
  121. orderGood.Order = order.ID
  122. }
  123. //批量插入orderGoods
  124. if result := tx.CreateInBatches(orderGoods, 100); result.RowsAffected == 0 {
  125. tx.Rollback()
  126. fmt.Println("创建订单失败")
  127. }
  128. tx.Commit()
  129. //查询方式条件有三种 1. string 2. struct 3. map
  130. }

image.png
image.png
image.png
image.png
image.png

  1. package main
  2. import (
  3. "log"
  4. "os"
  5. "time"
  6. "gorm.io/driver/mysql"
  7. "gorm.io/gorm"
  8. "gorm.io/gorm/logger"
  9. )
  10. // `User` 属于 `Company`,`CompanyID` 是外键
  11. type User struct {
  12. gorm.Model
  13. Name string
  14. CompanyID int //数据库中存储的字段company_id
  15. Company Company
  16. }
  17. type Company struct {
  18. ID int
  19. Name string
  20. }
  21. func main() {
  22. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  23. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  24. newLogger := logger.New(
  25. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  26. logger.Config{
  27. SlowThreshold: time.Second, // 慢 SQL 阈值
  28. LogLevel: logger.Info, // Log level
  29. Colorful: true, // 禁用彩色打印
  30. },
  31. )
  32. // 全局模式
  33. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  34. Logger: newLogger,
  35. })
  36. if err != nil {
  37. panic(err)
  38. }
  39. //db.AutoMigrate(&User{}) //新建了user表和company表,并设置了外键
  40. //db.Create(&User{
  41. // Name: "bobby",
  42. // Company: Company{
  43. // Name:"慕课网",
  44. // },
  45. //})
  46. db.Create(&User{
  47. Name: "bobby2",
  48. Company: Company{
  49. ID:1,
  50. },
  51. })
  52. }
  1. package main
  2. import (
  3. "database/sql"
  4. "gorm.io/gorm/schema"
  5. "log"
  6. "os"
  7. "time"
  8. "gorm.io/driver/mysql"
  9. "gorm.io/gorm"
  10. "gorm.io/gorm/logger"
  11. )
  12. type Language struct {
  13. gorm.Model
  14. Name string
  15. AddTime sql.NullTime //每个记录创建的时候自动加上当前时间加入到AddTime中
  16. }
  17. //func (l *Language) BeforeCreate(tx *gorm.DB) (err error){
  18. // l.AddTime = time.Now()
  19. // return
  20. //}
  21. //在gorm中可以通过给某一个struct添加TableName方法来自定义表名
  22. func (Language) TableName() string{
  23. return "my_language"
  24. }
  25. /*
  26. 1. 我们自己定义表名是什么
  27. 2. 统一的给所有的表名加上一个前缀
  28. */
  29. func main() {
  30. // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  31. dsn := "root:root@tcp(192.168.0.104:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
  32. newLogger := logger.New(
  33. log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
  34. logger.Config{
  35. SlowThreshold: time.Second, // 慢 SQL 阈值
  36. LogLevel: logger.Info, // Log level
  37. Colorful: true, // 禁用彩色打印
  38. },
  39. )
  40. // 全局模式
  41. //NamingStrategy和Tablename不能同时配置,
  42. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  43. NamingStrategy:schema.NamingStrategy{//配置表名前缀
  44. TablePrefix: "mxshop_",
  45. },
  46. Logger: newLogger,
  47. })
  48. if err != nil {
  49. panic(err)
  50. }
  51. db.AutoMigrate(&Language{})
  52. db.Create(&Language{
  53. Name:"python",
  54. })
  55. }