当前位置: 移动技术网 > IT编程>脚本编程>Go语言 > gorm系列-model

gorm系列-model

2020年04月29日  | 移动技术网IT编程  | 我要评论

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{})
}

主键、表名、列名的约定

主键(primary key)

gorm 默认会使用名为id的字段作为表的主键。

自定义主键

// 使用`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{})
}

表名(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{})   //重新建了一个表  不会删除
}


表名判断

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


删除表名: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{})
}


自定义表名

//使用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;
	}

列名

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

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{})
}

时间戳跟踪

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字段为当前时间,而不是直接将记录从数据库中删除。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网