Оригинальный автор, публичный аккаунт [программист чтение], прошу обратить внимание на паблик-аккаунт, просьба указывать источник перепечатываемой статьи.
При разработке приложения, вообще говоря, мы сначала проектируем таблицу данных, а затем используем язык разработки для построения соответствующей модели данных.Однако то, о чем мы будем говорить сегодня, — это процесс обратной операции, то есть, как определитьGORM
модель данных фреймворка, а затем, выполнивGROM
Приложение, написанное во фрейме, использует определенную модель данных для создания соответствующей таблицы данных в базе данных.
Итак, нам нужно поговорить о том, как определениеGORM
модель данных.
определение модели
Как правило, мы говоримGROM
Определение модели относится к определению структуры, представляющей таблицу данных (struct
), то мы можем использоватьGROM
Платформа может отображать структуру в таблицу данных соответствующей реляционной базы данных или запрашивать данные в таблице данных для заполнения структуры, как показано ниже, мы определяем именованныйPost
структура.
type Post struct {
PostId int
Uid int
Title string
Content string
Type int
CreatedAt time.Time
UpdatedAt time.Time
}
Создание структуры — это только первый шаг, но давайте не будем беспокоиться о том, как сначала создать таблицу данных.Сначала мы должны понять правила сопоставления между структурой и таблицей данных.Основные моменты заключаются в следующем:
Struct tags
мы знаем,Go
Структура языка поддерживает использованиеtags
Расширьте дополнительную информацию для каждого поля структуры, например, используя стандартную библиотеку.encoding/json
пакет дляJSON
При кодировании можно использоватьtags
Расширение, которое кодирует дополнительную информацию.
GROM
Фреймворк имеет свойtags
конвенции, следующим образом:
Column 指定列名
Type 指定列数据类型
Size 指定列大小, 默认值255
PRIMARY_KEY 将列指定为主键
UNIQUE 将列指定为唯一
DEFAULT 指定列默认值
PRECISION 指定列精度
NOT NULL 将列指定为非 NULL
AUTO_INCREMENT 指定列是否为自增类型
INDEX 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引
UNIQUE_INDEX 和 INDEX 类似,只不过创建的是唯一索引
EMBEDDED 将结构设置为嵌入
EMBEDDED_PREFIX 设置嵌入结构的前缀
- 忽略此字段
GROM также поддерживает некоторые соглашения тегов, связанные с таблицами данных.Когда у меня будет возможность поговорить об ассоциации таблиц данных GROM, я расскажу об этом.
Перечисленные выше теги, поддерживаемые GORM, удобны для настройки правил сопоставления между полями структуры и полями таблицы данных.В следующем коде мы даемPost
Настройка структурыtags
Развернуть следующим образом:
type Post struct {
PostId int `gorm:"primary_key;auto_increment"`
Uid int `gorm:"type:int;not null"`
Title string `gorm:"type:varchar(255);not null"`
Content string `gorm:"type:text;not null"`
Type uint8 `gorm:"type:tinyint;default 1;not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt time.Time
}
Из приведенного выше примера мы видим, чтоGORM
Определите формат тегов для полей модели данных, каждое поле может использовать несколько типовtags
Информация, разделяйте теги точкой с запятой.
соглашение
Помимо вышеперечисленногоtags
В дополнение к определению правил сопоставления между полями, когда Go Maps структуры в таблицах реляционных данных, он также имеет свой собственный набор конвенций, или конвенций, которые в основном следующие:
первичный ключ
Гром согласился, вообще в модели данныхID
Поля сопоставляются с первичным ключом таблицы данных, как определено ниже.TestModel
,ID
первичный ключ,TestModel
изID
Тип данныхstring
,еслиID
Тип данныхint
, GROM также установитAUTO_INCREMENT
,использоватьID
стать автоматически увеличивающимся первичным ключом.
type TestModel struct{
ID int
Name string
}
Конечно, мы также можем настроить имя поля первичного ключа, как указано выше.Post
структура, мы устанавливаемPostId
Поле является первичным ключом.Если мы определим другие поля как первичный ключ, то даже если все еще естьID
поле,GROM
рамки не будутID
Поле используется как первичный ключ.
type Post struct {
ID int
PostId int `gorm:"primary_key;auto_increment"`
Uid int `gorm:"type:int;not null"`
Title string `gorm:"type:varchar(255);not null"`
Content string `gorm:"type:text;not null"`
Type uint8 `gorm:"type:tinyint;default 1;not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt time.Time
}
По этому мыPost
добавить один в структуруID
поле,PostId
Поле по-прежнему является первичным ключом, в данных используется следующееdesc posts
Результат, напечатанный оператором:
Правила сопоставления таблиц данных
Когда мы используем структуру для создания таблицы данных, имя таблицы данных по умолчанию соответствует множественной форме структуры в нижнем регистре, например структураPost
Соответствующее имя таблицы данныхposts
, Конечно, мы также можем указать имя таблицы данных, соответствующее структуре, вместо использования значения по умолчанию.
добавить в структуруTableName()
метод, с помощью которого вы можете вернуть имя пользовательской таблицы данных следующим образом:
//指定Post结构体对应的数据表为my_posts
func (p Post) TableName() string{
return "my_posts"
}
префикс таблицы данных
Помимо указания имени таблицы данных, мы также можем переопределитьgorm.DefaultTableNameHandler
Эта переменная, чтобы можно было указать единый префикс таблицы данных для всех таблиц данных, выглядит следующим образом:
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "tb_" + defaultTableName;
}
В этом случае через структуруPost
Имя созданной таблицы данныхtb_posts
.
Правила сопоставления полей
Правила сопоставления структуры имени к таблице данных на таблицу данных по умолчанию Поле данных правила сопоставления по умолчанию - это разделенная таблица. Начните с заглавной буквы каждого слова подчеркиваются как имя сложной структуры, а структура поля, следующим образом:
type Prize struct {
ID int
PrizeName string
}
структура вышеPrize
серединаPrizeName
Таблица данных, соответствующая полю,prize_name
, но мы ставимPrizeName
изменить наPrizename
, соответствующее имя поля таблицы данныхprizename
, это связано с тем, что разделяются только слова в начале поля в верхнем регистре.
Конечно, мы также можем определить поле структурыtags
Расширенная информация, так что правила отображения из полей структуры в поля таблицы данных находятся вtags
определено в.
отслеживание времени
Ранее мы говорили, что если в структуре есть имяID
поле, тоGORM
Фреймворк будет использовать это поле как первичный ключ таблицы данных, кроме того, если структура имеетCreatedAt
,UpdatedAt
,DeletedAt
Если эти поляGROM
Фреймворк также выполнит некоторую специальную обработку, правила следующие:
CreatedAt:新增数据表记录的时候,会自动写入这个字段。
UpdatedAt:更新数据表记录的时候,会自动更新这个字段。
DeletedAt:当执行软删除的时候,会自动更新这个字段,表示删除时间
gorm.Model
Так как если структура имеетID
,CreatedAt
,UpdatedAt
,DeletedAt
Эти более общие поля,GORM
Фреймворк будет автоматически обрабатывать эти поля, поэтому, если нашей структуре нужны эти поля, мы можем напрямую встроить их в пользовательскую структуру.gorm.Model
структура,gorm.Model
Структура выглядит следующим образом:
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
Итак, если мы находимся в структуреPrize
встроенный вgorm.Model
,следующее:
type Prize struct{
gorm.Model
Name string
}
В этом случае структураPrize
Содержит пять полей.
миграция базы данных
Мы говорим о миграции базы данных, то есть благодаря использованиюGROM
Предоставляется набор методов, в соответствии с определенными правилами модели данных, создание, удаление таблиц данных и другие операции, то есть операции DDL в базе данных.
GORM
Предоставляет методы для выполнения операций DDL в базах данных, главным образом в следующих категориях:
Работа с таблицей данных
//根据模型自动创建数据表
func (s *DB) AutoMigrate(values ...interface{}) *DB
//根据模型创建数据表
func (s *DB) CreateTable(models ...interface{}) *DB
//删除数据表,相当于drop table语句
func (s *DB) DropTable(values ...interface{}) *DB
//相当于drop table if exsist 语句
func (s *DB) DropTableIfExists(values ...interface{}) *DB
//根据模型判断数据表是否存在
func (s *DB) HasTable(value interface{}) bool
операция столбца
//删除数据表字段
func (s *DB) DropColumn(column string) *DB
//修改数据表字段的数据类型
func (s *DB) ModifyColumn(column string, typ string) *DB
индексная операция
//添加外键
func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB
//给数据表字段添加索引
func (s *DB) AddIndex(indexName string, columns ...string) *DB
//给数据表字段添加唯一索引
func (s *DB) AddUniqueIndex(indexName string, columns ...string) *DB
Пример простого кода переноса данных
Обратите внимание, что в следующем примере программы
db
Переменное представлениеgorm.DB
Object, процесс его инициализации можете сослаться на мою предыдущую статью.
type User struct {
Id int //对应数据表的自增id
Username string
Password string
Email string
Phone string
}
func main(){
db.AutoMigrate(&Post{},&User{})//创建posts和users数据表
db.CreateTable(&Post{})//创建posts数据表
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&Post{})//创建posts表时指存在引擎
db.DropTable(&Post{},"users")//删除posts和users表数据表
db.DropTableIfExists(&Post{},"users")//删除前会判断posts和users表是否存在
//先判断users表是否存在,再删除users表
if db.HasTable("users") {
db.DropTable("users")
}
//删除数据表字段
db.Model(&Post{}).DropColumn("id")
//修改字段数据类型
db.Model(&Post{}).ModifyColumn("id","varchar(255)")
//建立posts与users表之间的外键关联
db.Model(&Post{}).AddForeignKey("uid", "users(id)", "RESTRICT", "RESTRICT")
//给posts表的title字段添加索引
db.Model(&Post{}).AddIndex("index_title","title")
//给users表的phone字段添加唯一索引
db.Model(&User{}).AddUniqueIndex("index_phone","phone")
}
резюме
Вы спросите, а не достаточно ли создавать и удалять таблицы данных прямо в БД? Зачем эти операции в приложении? Потому что иногда мы не можем войти в систему базы данных или нам нужно разработать приложение, которое может управлять базой данных.GROM
Эти возможности миграции базы данных, предоставляемые платформой, пригодятся.
Ваше внимание — самое большое поощрение на моем писательском пути!