gorm

Go Gorm

1. 指南

The fantastic ORM library for Golang aims to be developer friendly.

特性

  1. 全功能 ORM
  2. 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
  3. Create,Save,Update,Delete,Find 中钩子方法
  4. 支持 Preload、Joins 的预加载
  5. 事务,嵌套事务,Save Point,Rollback To Saved Point
  6. Context、预编译模式、DryRun 模式
  7. 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
  8. SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
  9. 复合主键,索引,约束
  10. Auto Migration
  11. 自定义 Logger
  12. 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
  13. 每个特性都经过了测试的重重考验
  14. 开发者友好

安装

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

func main() {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

2.Has One 模式

Has One
Has One 与另一个模型建立一对一的关系,但他和一对一的关系有些许不同。 这种关联表明一个模型的每个实例都包好货拥有另一个模型的实例。

现在有两张表user和company表示一个用户只能拥有一个公司
表结构分别为

user

type User struct {
	Id         int       `gorm:"primaryKey;column:id;autoIncrement" `
	UserName   string    `gorm:"column:user_name" json:"userName"`
	Age        int       `gorm:"column:age" json:"age"`
	Email      string    `gorm:"column:email" json:"email"`
	CreateTime time.Time `gorm:"column:create_time;autoCreateTime"`
	Company    Company   `gorm:"foreignKey:YhId"` // 表示 User表中的字段Company 通过Company中的YhId进行关联 关联内容为 User的主键
	//UserRole   UserRole  `gorm:"foreignKey:YhId"`
}

func (u User) TableName() string {
	return "user"
}

company

type Company struct {
	Id          int    `gorm:"primaryKey;column:id;autoIncrement"`
	YhId        string `gorm:"column:yh_id"`
	CompanyName string `gorm:"column:company_name"`
}

func (Company) TableName() string {
	return "company"
}

2.1 关联查询

func (u UserController) List(c *gin.Context) {
	var users []models.User

	tx := models.DB.Preload("Company").Find(&users)
	if tx.Error != nil {
		c.JSON(http.StatusOK, gin.H{
			"message": "查询失败",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "查询成功",
		"data":    users,
	})
}

2.2 分析

实际上查询分为两步 第一步预加载实际上SQL为
SELECT * FROM company WHERE company.yh_id IN ("查出User表中的ID集合")
第二步查
SELECT * FROM USER

2.3 注意事项

  1. 预加载必须操作
  2. 如果存在一对多的情况 相当于是把结果存储到了一个Map中,后续会根据关联的外键随机获取一个(会导致不能查询出所有的数据,这种情况应该使用one to many的情况)
  3. 预加载可以使用join的方式 详情见URL: https://gorm.io/zh_CN/docs/preload.html
posted @ 2023-11-10 14:52  ChenLiuyu  阅读(22)  评论(0)    收藏  举报