GORM模型与约定

简介: GORM模型与约定

模型

模型的概念

在使用GORM时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体(模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成)。总之意思就是前面一篇概述中用的结构体,在GORM中就称之为模型,模型是与数据表进行映射的结构体。

例如这个UserInfo 结构体,就是我们完全自定义的模型

type UserInfo struct {
  ID     uint
  Name   string
  Gender string
  Hobby  string
}

 为了方便模型定义,GORM内置了一个gorm.Model结构体。其包含了4个字段,一个ID作为主键,3个时间相关的字段。一般将这个gorm.Model嵌入我们自定义的结构体中使用

// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models
//    type User struct {
//      gorm.Model
//    }
type Model struct {
  ID        uint `gorm:"primary_key"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt *time.Time `sql:"index"`
}

将gorm.Model嵌入自定义的模型中

// UserInfo 用户信息
type UserInfo struct {
  Name   string
  Gender string
  Hobby  string
}

模型的定义

  更多的字段标签相关的,之间看官方文档即可字段标签

type User struct {
  gorm.Model   //内嵌gorm.Model
  Name         string
  Age          sql.NullInt64 //类型零值
  Birthday     *time.Time
  Email        string  `gorm:"type:varchar(100);unique_index"` //变长类型,最长255,创建唯一索引
  Role         string  `gorm:"size:255"`                       // 设置字段大小为255
  MemberNumber *string `gorm:"unique;not null"`                // 设置会员号(member number)唯一并且不为空
  Num          int     `gorm:"AUTO_INCREMENT"`                 // 设置 num 为自增类型
  Address      string  `gorm:"index:addr"`                     // 给address字段创建名为addr的索引
  IgnoreMe     int     `gorm:"-"`                              // 忽略本字段
}

约定

主键的约定

  GORM 默认会使用名为ID的字段作为表的主键。

type User struct {
  ID   string // 名为`ID`的字段会默认作为表的主键
  Name string
}
// 通过tag设置,使用`Name`作为主键
type User struct {
  ID   int64
  Name string `gorm:"primary_key"`
}

表名的约定

  表名默认:将驼峰的结构体名称用_下划线分隔,并在末尾增加复数s

//UserInfo -> user_infos
type User struct {} // 默认表名是 `users`
// 将 User 的表名设置为 `profiles`
func (User) TableName() string {
  return "profiles"
}
func (u User) TableName() string {
  if u.Role == "admin" {
    return "admin_users"
  } else {
    return "users"
  }
}
// 禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user`,没有s
db.SingularTable(true)

可以通过Table()指定表名

type User struct {} // 默认表名是 `users`
// 使用User结构体创建名为`my_users`的表
db.Table("my_users").CreateTable(&User{})
var my_users []User
// SELECT * FROM deleted_users;
db.Table("my_users").Find(&deleted_users)
// DELETE FROM my_users WHERE name = 'wxf';
db.Table("my_users").Where("name = ?", "wxf").Delete()

 GORM还支持更改默认表名称规则:

gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string  {
  return "prefix_" + defaultTableName;
}

列名的约定

  列名由字段名称进行下划线分割来生成

type User struct {
  ID        uint      // column name is `id`
  Name      string    // column name is `name`
  Birthday  time.Time // column name is `birthday`
  CreatedAt time.Time // column name is `created_at`
}

可以使用结构体tag指定列名:

type Animal struct {
  AnimalId    int64     `gorm:"column:beast_id"`         // set column name to `beast_id`
  Birthday    time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
  Age         int64     `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
}

gorm.Model的约定

  如果模型有 CreatedAt字段,该字段的值将会是初次创建记录的时间。

db.Create(&user) // `CreatedAt`将会是当前时间
// 可以使用`Update`方法来改变`CreateAt`的值
db.Model(&user).Update("CreatedAt", time.Now())

 如果模型有UpdatedAt字段,该字段的值将会是每次更新记录的时间。

db.Save(&user) // `UpdatedAt`将会是当前时间
db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`将会是当前时间

 如果模型有DeletedAt字段,调用Delete删除该记录时,将会设置DeletedAt字段为当前时间,而不是直接将记录从数据库中删除,即软删除。


目录
相关文章
|
4月前
|
人工智能 JSON 安全
大模型应用开发中MCP与Function Call的关系与区别
MCP与Function Call是大模型应用中两大关键技术。MCP作为标准化协议,打通模型与外部工具的通用连接;Function Call则是模型调用外部功能的具体机制。前者如“桥梁”,后者似“工具”,二者互补协同,推动AI应用向更开放、灵活、安全的方向演进,构建“意图解析-协议传输-工具执行”的分层架构新范式。
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
1226 9
|
网络协议 Linux Android开发
深入探索Android系统架构与性能优化
本文旨在为读者提供一个全面的视角,以理解Android系统的架构及其关键组件。我们将探讨Android的发展历程、核心特性以及如何通过有效的策略来提升应用的性能和用户体验。本文不包含常规的技术细节,而是聚焦于系统架构层面的深入分析,以及针对开发者的实际优化建议。
471 21
|
存储 缓存 安全
Go Channel详解
Go Channel详解
743 1
|
存储 前端开发 JavaScript
ACEeditor使用手册(二)
ACEeditor使用手册(二)
966 0
|
Go 开发者
为什么在 Golang 中使用 Goto 语句?
【8月更文挑战第31天】
585 0
|
存储 监控 关系型数据库
解密MySQL中的临时表:探究临时表的神奇用途
解密MySQL中的临时表:探究临时表的神奇用途
1344 3
|
存储 SQL 开发框架
Flutter数据库操作看这一篇就够了
Flutter数据库操作看这一篇就够了
Flutter数据库操作看这一篇就够了
|
算法 项目管理 开发者
【Conan 入门教程 】深入解析Conan中的依赖关系的定义方法(In-depth Analysis of Dependency Definition Methods in Conan)
【Conan 入门教程 】深入解析Conan中的依赖关系的定义方法(In-depth Analysis of Dependency Definition Methods in Conan)
706 0
|
SQL Go 数据库
gorm 教程 一(1)
gorm 教程 一
212 0

热门文章

最新文章