栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

gorm v2.0简单使用总结

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

gorm v2.0简单使用总结

数据库连接
import (
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
   "testing"
)
​
// 测试连接mysql
func TestConnectMysql(t *testing.T) {
   dsn := "root:1234@(127.0.0.1:3306)/SimpleGorm?charset=utf8mb4&parseTime=True&loc=Local"
   db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

gorm.Open第一个参数是Dialector类型

  • 简单的,直接按照数据库的地址构造dialector 即mysql.Opne(dsn)

  • 复杂的,支持MySQL的配置

    mysql.New(mysql.Config{
      DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
      DefaultStringSize: 256, // string 类型字段的默认长度
      DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
      DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
      DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
      SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
    })

gorm.Open的第二个参数是Option类型,可以设置gorm的配置

  • 支持的配置有如下

    type Config struct {
      SkipDefaultTransaction   bool             //跳过默认事务
      NamingStrategy           schema.Namer     // 表和列命名策略
      Logger                   logger.Interface // 配置日志
      NowFunc                  func() time.Time // 更改创建时间使用的函数
      DryRun                   bool         //生成 SQL 但不执行,可以用于准备或测试生成的 SQL
      PrepareStmt              bool     //在执行任何 SQL 时都会创建一个 prepared statement 并将其缓存,以提高后续的效率
      DisableNestedTransaction bool     // 禁用嵌套事务
      AllowGlobalUpdate        bool     // 启用全局 update/delete
      DisableAutomaticPing     bool     //GORM 会自动 ping 数据库以检查数据库的可用性.可以禁用
      DisableForeignKeyConstraintWhenMigrating bool //GORM 会自动创建外键约束,若要禁用该特性 建议禁用物理外键
    }
  • 使用示例,只用了一个配置

    db, _ = gorm.Open(mysql.Open(dsn), &gorm.Config{
       DisableForeignKeyConstraintWhenMigrating: true,    //禁用物理外键
    })
标签的使用

可用标签见文档

示例:

// 定义一个玩家结构
type Player struct {
   ID           uint      `gorm:"primaryKey;comment:主键"`
   UID       uint      `gorm:"unique;comment:玩家唯一id"`
   Username   string        `gorm:"comment:玩家用户名"`
   Password   string    `gorm:"comment:密码"`
   CreatedAt  time.Time  `gorm:"comment:创建时间;autoCreateTime"`
   UpdateAt   time.Time  `gorm:"comment:创建时间;autoUpdateTime"`
   DeleteAt   gorm.DeletedAt `gorm:"删除时间"`
}

gorm也提供了基本的模型,已经包含了如下字段:

type Model struct {
   ID        uint `gorm:"primarykey"`
   CreatedAt time.Time
   UpdatedAt time.Time
   DeletedAt DeletedAt `gorm:"index"`
}

自己创建模型时,直接继承就可以了,例如

type Player struct {
   gorm.Model          // gorm提供的结构体,自带idCreateatupdateatdeleteat
   UID       uint      `gorm:"unique;comment:玩家唯一id"`
   Username   string        `gorm:"comment:玩家用户名"`
   Password   string    `gorm:"comment:密码"`
}
基本的增删改查

增删改查可以根据返回值的RowsAffected来判断,表示数据库操作影响的行数.

gorm会自动跳过软删除的数据

gorm执行前添加Debug会进入调试模式,打印所有sql

db.Debug().Where("username like ?","%夏目%").Find(&newPlayers)  // 加入DeBug()方便打印sql进行调试

创建表

exist := db.Migrator().HasTable(&Player{})  // 查看Player表是否存在
if !exist{
    db.AutoMigrate(&Player{})
}

插入

player := Player{
   Username: "夏目",
   Password: "1234",
   UID: 12345678,
}
result := db.Save(&player)

删除

db.First(&player)		// 删除第一条数据
result := db.Delete(&player)

查询单条

db.First(&player)		//首条记录
db.First(&newPlayer,4)	// 主键查询
db.Where("Username = ?","xiamu").First(&player)  //条件查询

查询多条

db.Find(&players)
db.Debug().Where("username like ?","%夏目%").Find(&newPlayers) 

一对一

一对一包含两种, has one以及belongs to

hasOne
type Player struct {
   gorm.Model          // gorm提供的结构体,自带idCreateatupdateatdeleteat
   UID       uint      `gorm:"unique;comment:玩家唯一id"`
   Username   string        `gorm:"comment:玩家用户名"`
   Password   string    `gorm:"comment:密码"`
   Role      Role
}

// 定义一个游戏角色 使用playerId作为外键
type Role struct {
	gorm.Model
	PlayerId 	uint		// 默认使用user.uid作为外键
	Name 		string 		`gorm:"comment:游戏角色名"`
	Level 		string		`gorm:"comment:游戏角色登记"`
	Coins  		uint32		`gorm:"comment:游戏角色金币数"`
}

Player has Role 每个玩家包含一个角色.

  • Player中要包含一个Role结构体

  • Role中要包含Player的外键,默认为PlayerId (结构体名Id)

  • 支持自定义外键

    Phone		Phone		`gorm:"foreignKey:UID"`		// 自定义外键 Role中的外键也要对应修改
  • 也支持自定义引用 必须是有效的外键,即unique列

belongsTo
type Player struct {
   gorm.Model          // gorm提供的结构体,自带idCreateatupdateatdeleteat
   Username   string        `gorm:"comment:玩家用户名"`
   Password   string    `gorm:"comment:密码"`
   SwordID       uint      `gorm:"comment:宝剑ID"`
   Sword     Sword
}

type Sword struct {
	gorm.Model
	Name     	string		`gorm:"comment:宝剑名;unique"`
}

一把Sword属于一个Player

  • Player中包含Sword的主键以及Sword的结构体

  • 支持拥有者(Player)中修改Player.SwordName的名字

    type Player struct {
    	...
    	MySwordID	string
    	Sword		Sword		`gorm:"foreignKey:MySwordID"`
    }
  • 支持修改引用: 可以修改Player.SwordID的内容为指定的Sword中的字段

    Sword     Sword	 `gorm:"references:Name"`	// SwordID保存的即变为Sword.Name
增删改查

增:

player1 := Player{
   Username: "周芷若",
   Password: "1234",
   Sword: Sword{
      Name: "倚天剑",
   },
}

player2 := Player{
   Username: "张无忌",
   Password: "1234",
   Sword: Sword{
      Name: "屠龙刀",
   },
}

db.Create([]Player{player1,player2})

删除和普通表的操作一样.

更新和查询见关联查询以及preload的用法

一对多

数据关系: player和hero是一对多关系

type Player struct {
   gorm.Model          // gorm提供的结构体,自带idCreateatupdateatdeleteat
   Username   string        `gorm:"comment:玩家用户名"`
   Password   string    `gorm:"comment:密码"`
   //Heros       []Hero
   // 第二种
   //Heros       []Hero    `gorm:"foreignKey:PlayerKey"`  // 定义外键的名字
   // 第三种
   Heros     []Hero    `gorm:"foreignKey:PlayerName;references:Username"` // 自定义外键引用
}


// hero   player可以拥有多个hero
type Hero struct {
   gorm.Model
   Name      string    `gorm:"comment:英雄名字"`
   HP       int32     `gorm:"comment:血量"`
   //PlayerID uint
   // 第二种
   //PlayerKey    uint
   // 第三种
   PlayerName     string
}

插入数据

func TestInsert(t *testing.T){
   hero1 := Hero{
      Name: "卡莎",
      HP: 300,
   }
   hero2 := Hero{
      Name: "瑞兹",
      HP: 500,
   }

   player := Player{
      Username: "夏目",
      Password: "1234",
      Heros: []Hero{hero1,hero2},
   }

   result := db.Create(&player)
   fmt.Println("插入行数:",result.RowsAffected)
}
多对多

每个player都有多个手柄

// 每一个player有多个手柄
type Player struct {
   gorm.Model
   Name      string
   Gamepads   []Gamepad     `gorm:"many2many:player_gamepad"`
   Friends       []Player      `gorm:"many2many:player_friends"`     //自引用
}

// 游戏手柄
type Gamepad struct {
   gorm.Model
   Brand     string
}

插入数据

func TestInsert(t *testing.T) {
   gamepad1 := Gamepad{
      Brand: "Nintendo",
   }

   gamepad2 := Gamepad{
      Brand: "PS4",
   }
   db.Create([]*Gamepad{&gamepad1,&gamepad2})    // 插入手柄数据

   gamepads := make([]Gamepad,0)
   db.Find(&gamepads)

   player1 := Player{
      Name: "马里奥",
      Gamepads: gamepads,       // 每个player都有各种手柄
   }

   player2 := Player{
      Name: "路易吉",
      Gamepads: gamepads,
   }

   result := db.Create([]*Player{&player1,&player2})  //插入数据,gorm自动更新中间表
   if result.RowsAffected==0 {
      fmt.Println("插入失败")
   }else{
      fmt.Println("插入成功",result.RowsAffected)
   }
}
关联

一对一; 一对多; 多对多的查询都需要使用关联查询.. 文档写的很好了,我就懒得写了

关键字: Assocaition

功能包括:

  • 查找所有关联

  • 添加关联: 例如给player添加新的gamepad

  • 替换关联

  • 删除关联

  • 清空关联

  • 关联计数

  • 删除数据,如果要删除它关联的数据,要使用Select删除

preload

查询数据时, 如果要把关联的数据一并查找出来, 可以使用预加载

  • 支持全部查找

  • 支持带条件的预加载

  • 也支持自定义的预加载

    db.Preload("Orders", func(db *gorm.DB) *gorm.DB {
      return db.Order("orders.amount DESC")
    }).Find(&users)
钩子

如果一个模型 struct要在创建查询更新删除操作时, 添加自定义的方法, 可以使用钩子函数来实现, 这样gorm就会自动在执行相关操作时, 执行对应的函数

  • 创建时

    • BeforeSave

    • BeforeCrete

    • AfterCreate

    • AfterSave

  • 更新时

    • BeforeSave

    • BeforeUpdate

    • AfterUpdate

    • AfterSave

  • 删除时

    • BeforeDelete

    • AfterDelete

  • 查询时

    • AfterFind 比如把密码加密,

原生

db.Raw(“原生sql”).Scan(查找对象)

db.Exec(“原生sql”)

迁移

Migrator方法包含了很多对数据表的操作方法

  • AutoMigrate 自动迁移

  • CurrentDatabase 当前数据库

  • FullDataTypeOf(Field) 列的数据类型

表的操作

  • CreateTable 创建表

  • DropTable 删除表

  • HasTable

  • RenameTable

列的操作

  • AddColumn

  • DropColumn

  • AlterColumn

  • HasColumn

  • RenameColumn

  • MigrateColumn

  • ColumnTypes

约束操作

  • CreateConstraint

  • DropConstraint

  • HashConstraint

索引操作

  • CreateIndex

  • DropIndex

  • HasIndex

  • RenameIndex

事务
// 开始事务
tx := db.Begin()
// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)// ...
// 遇到错误时回滚事务
tx.Rollback()
// 否则,提交事务
tx.Commit()

如果需要回滚到指定的地方,可以使用:

  • tx.SavePoint(“name”)

  • tx.RollbackTo(“name”)

回滚到指定的保存点

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/990979.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号