• gorm系列-model


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

  • 相关阅读:
    将配置文件自动复制到vs的测试项目中
    用索引器简化的C#类型信息访问
    Requested Clipboard operation did not succeed的解决办法
    在win2003上IIS部署可能出现的问题的解决方案
    Login failed for user 'IIS APPPOOL\ASP.NET v4.0'.
    在Ubuntu虚拟机中配置bridge共享上网
    Ajax学习日志
    Workflow architecture in Windows SharePoint Services (version 3):WWF和WSS V3 的关系 无为而为
    使用BizTalk的必须关注:HWS已经死了,微软已经放弃HWS了,估计替代产品就WWF。(外加其它的宣告死亡的工具和API列表) 无为而为
    我想要求主管给我们升级电脑,但是主管不肯,大家报一报公司电脑的配置,我看我的电脑是不是最差的,顺便谈谈你们公司电脑硬件升级策略 无为而为
  • 原文地址:https://www.cnblogs.com/zisefeizhu/p/12788017.html
Copyright © 2020-2023  润新知