欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

gorm系列-model

程序员文章站 2024-01-03 20:15:34
[TOC] Gorm Model 在使用ORM工具时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针。同时也支持sql.Scanner(扫描)及driver.Valuer(驱动)接口(inte ......

gorm model

在使用orm工具时,通常我们需要在代码中定义模型(models)与数据库中的数据表进行映射,在gorm中模型(models)通常是正常定义的结构体、基本的go类型或它们的指针。同时也支持sql.scanner(扫描)及driver.valuer(驱动)接口(interfaces)

为了方便模型定义,gorm内置了一个gorm.model结构体。gorm.model是一个包含了id, createdat, updatedat, deletedat四个字段的golang结构体。

// gorm.model 定义
type model struct {
  id        uint `gorm:"primary_key"`
  createdat time.time
  updatedat time.time
  deletedat *time.time
}

可以将它嵌入到自己的模型中:

// 将 `id`, `createdat`, `updatedat`, `deletedat`字段注入到`user`模型中
type user struct {
  gorm.model
  name string
}

也可以完全自己定义模型:

// 不使用gorm.model,自行定义模型
type user struct {
  id   int
  createdat time.time
  updatedat time.time
  deletedat *time.time
  name string
}

模型定义示例

//定义模型
type user struct {
  gorm.model                         //内嵌gorm.model
  name         string                  //名字
  age          sql.nullint64        //年龄 零值类型
  birthday     *time.time
  email        string  `gorm:"type:varchar(100);unique_index"`  //结构体的tag
  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:"-"` // 忽略本字段
}

结构体标记(tags)

使用结构体声明模型时,标记(tags)是可选项。gorm支持以下标记:

支持的结构体标记(struct tags)
结构体标记(tag) 描述
column 指定列名
type 指定列数据类型
size 指定列大小, 默认值255
primary_key 将列指定为主键
unique 将列指定为唯一
default 指定列默认值
precision 指定列精度
not null 将列指定为非 null
auto_increment 指定列是否为自增类型
index 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引
unique_index index 类似,只不过创建的是唯一索引
embedded 将结构设置为嵌入
embedded_prefix 设置嵌入结构的前缀
- 忽略此字段
关联相关标记(tags)
结构体标记(tag) 描述
many2many 指定连接表
foreignkey 设置外键
association_foreignkey 设置关联外键
polymorphic 指定多态类型
polymorphic_value 指定多态值
jointable_foreignkey 指定连接表的外键
association_jointable_foreignkey 指定连接表的关联外键
save_associations 是否自动完成 save 的相关操作
association_autoupdate 是否自动完成 update 的相关操作
association_autocreate 是否自动完成 create 的相关操作
association_save_reference 是否自动完成引用的 save 的相关操作
preload 是否自动完成预加载的相关操作

例子

package main

import (
	"database/sql"
	"github.com/jinzhu/gorm"
	_"github.com/jinzhu/gorm/dialects/mysql"
	"time"

)

type user struct {
	gorm.model
	name         string
	age          sql.nullint64
	birthday     *time.time
	email        string  `gorm:"type:varchar(100);unique_index"`
	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:"-"` // 忽略本字段
}
func main() {
	db, err := gorm.open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parsetime=true&loc=local")
	if err != nil {
		panic(err)
	}
	defer  db.close()

	db.automigrate(&user{})
}

gorm系列-model

主键、表名、列名的约定

主键(primary key)

gorm 默认会使用名为id的字段作为表的主键。
gorm系列-model
自定义主键

// 使用`animalid`作为主键
type animal struct {
	animalid int64 `gorm:"primary_key"`
	name     string
	age      int64
}

func main() {
	db, err := gorm.open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parsetime=true&loc=local")
	if err != nil {
		panic(err)
	}
	defer  db.close()
	db.automigrate(&animal{})
}

gorm系列-model

表名(table name)

表名默认就是结构体名称的复数

// 使用`animalid`作为主键
type animal struct {
	animalid int64 `gorm:"primary_key"`
	name     string
	age      int64
}
//表名 紫色飞猪
func (animal) tablename()string {
	return "zisefeizhu"
}

func main() {
	db, err := gorm.open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parsetime=true&loc=local")
	if err != nil {
		panic(err)
	}
	defer  db.close()

	db.automigrate(&animal{})   //重新建了一个表  不会删除
}

gorm系列-model
表名判断

import (
	"database/sql"
	"github.com/jinzhu/gorm"
	_"github.com/jinzhu/gorm/dialects/mysql"
	"time"

)

// 使用`animalid`作为主键
type animal struct {
	animalid int64 `gorm:"primary_key"`
	name     string
	age      int64
}
//表名 紫色飞猪
//func (animal) tablename()string {
	//return "zisefeizhu"
//}

func (a animal) tablename() string  {
	if a.name == "admin" {
		return "admin_animal"
	} else {
		return "zisefeizhu"
	}
}

func main() {
	db, err := gorm.open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parsetime=true&loc=local")
	if err != nil {
		panic(err)
	}
	defer  db.close()

	animal := animal{
		animalid:1,
		name: "admin",
		age: 22,
	}
	db.automigrate(&animal)
}

gorm系列-model
删除表名:drop table biaoming;

表名禁用复数

import (
	"database/sql"
	"github.com/jinzhu/gorm"
	_"github.com/jinzhu/gorm/dialects/mysql"
	"time"

)

type user struct {
	gorm.model
	name         string
	age          sql.nullint64
	birthday     *time.time
	email        string  `gorm:"type:varchar(100);unique_index"`
	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:"-"` // 忽略本字段
}

// 使用`animalid`作为主键
type animal struct {
	animalid int64 `gorm:"primary_key"`
	name     string
	age      int64
}

func main() {
	db, err := gorm.open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parsetime=true&loc=local")
	if err != nil {
		panic(err)
	}
	defer  db.close()
	db.singulartable(true)  // 禁用默认表名的复数形式,如果置为 true,则 `user` 的默认表名是 `user`

	db.automigrate(&user{})
	db.automigrate(&animal{})
}

gorm系列-model
自定义表名

//使用user结构体创建名为zisefeizhu的表
	//db.table("zisefeizhu").createtable(&user{})  //表明最好有意义

var deleted_users []user
db.table("deleted_users").find(&deleted_users)
//// select * from deleted_users;

db.table("deleted_users").where("name = ?", "jinzhu").delete()
//// delete from deleted_users where name = 'jinzhu';

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

​ 建立一个项目,命名加一个统一的前缀

func main() {
	//修改默认的表明规则
	gorm.defaulttablenamehandler = func (db *gorm.db, defaulttablename string) string  {
		return "zisefeizhu_" + defaulttablename;
	}

gorm系列-model

列名

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

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`
}

例子

import (
	"database/sql"
	"github.com/jinzhu/gorm"
	_"github.com/jinzhu/gorm/dialects/mysql"
	"time"

)

type user struct {
	gorm.model
	name         string
	age          sql.nullint64  `gorm:"column:age_of_the_beast"`
	birthday     *time.time
	email        string  `gorm:"type:varchar(100);unique_index"`
	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:"-"` // 忽略本字段
}

func main() {
	//修改默认的表明规则
	gorm.defaulttablenamehandler = func (db *gorm.db, defaulttablename string) string  {
		return "zisefeizhu_" + defaulttablename;
	}
	db, err := gorm.open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parsetime=true&loc=local")
	if err != nil {
		panic(err)
	}
	defer  db.close()
	db.singulartable(true)  // 禁用默认表名的复数形式,如果置为 true,则 `user` 的默认表名是 `user`

	db.automigrate(&user{})
}

gorm系列-model

时间戳跟踪

createdat

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

db.create(&user) // `createdat`将会是当前时间
// 可以使用`update`方法来改变`createat`的值
db.model(&user).update("createdat", time.now())

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

db.save(&user) // `updatedat`将会是当前时间
db.model(&user).update("name", "jinzhu") // `updatedat`将会是当前时间

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

上一篇:

下一篇: