乐趣区

关于golang:基础配置篇数据表和golang结构体关联和映射关系处理

上一节咱们介绍了 gorm 的连贯和配置,并且咱们也在数据库中创立了 admins、article_data、articles、attachments、categories 五个表。然而咱们还没有将它和 golang 联合在一起,咱们的博客网站还不能从数据库读写数据。须要应用 gorm 来读写数据,咱们还须要先给每个表定义一个模型(struct)。

后面建设目录的时候,咱们曾经定义了数据库模型文件寄存的目录 为model 文件夹。因而咱们在 model 目录别离按表名称的复数模式创立对应的 go 文件,并定义对应的模型构造体。

admin.go 文件的 admins 表

type Admin struct {Id          uint `json:"id" gorm:"column:id;type:int(10) unsigned not null AUTO_INCREMENT;primaryKey;"`
    UserName    string `json:"user_name" gorm:"column:user_name;type:varchar(16) not null;default:'';index:idx_user_name"`
    Password    string `json:"-" gorm:"column:password;type:varchar(128) not null;default:''"`
    Status      uint   `json:"status" gorm:"column:status;type:tinyint(1) unsigned not null;default:0;index:idx_status"`
    CreatedTime int64   `json:"created_time" gorm:"column:created_time;type:int(11) not null;default:0;index:idx_created_time"`
    UpdatedTime int64   `json:"updated_time" gorm:"column:updated_time;type:int(11) not null;default:0;index:idx_updated_time"`
    DeletedTime int64   `json:"-" gorm:"column:deleted_time;type:int(11) not null;default:0"`
}

表名称的构造体是表名的复数模式,因为默认 gorm 在读取表的时候,会应用复数构造体名称的复数模式作为表名。当然,咱们也能够通过自定义表名的模式,来从新定义表名,不应用 gorm 的默认表名:

func (Admin) TableName() string {return "admins"}

自定义表名应用 TableName() 函数来重写。

同时要留神,构造体名称肯定要应用驼峰命名法令来命名,单词首字母大写。构造体外部字段也是如此,必须要应用驼峰命名法令来命名,首字母大写,内部能力拜访到这个字段,表字段和 json 字段则应用蛇形小写的命名形式,即它们的两个单词之间应用下划线 _ 来连贯。前面的构造体字段标记则是 golang 在解析这个字段的时候的变量,比方这些字段都应以了作为 json 输入的时候的字段名称。如果这个字段心愿在转换为 json 的时候,疏忽它,则将它的 json 标记为 - 即可,如:

Password    string `json:"-"`

前面的 gorm 标记,则是 gorm 对这个字段的数据库定义信息,它蕴含了这个字段在表中的字段名、字段类型、字段长度、无符号值、字段自增、关键字段、默认值、索引信息等内容,如果有必要,gorm 会依据这些内容来创立和更新 mysql 表信息。

同样地,如果心愿这个构造体中,某个字段不呈现在数据库中,同样能够应用 - 来疏忽它,如:

    Content int64   `json:"content" gorm:"-"`

这样这个字段能够通过内部赋值,并且在转换成 json 输入的时候,它是有值的,而它不会被写入到数据库中,gorm 应用 orm 查查询数据库的时候,它也不会被查问进去。

category.go 文件的 categories 表

type Category struct {Id          uint    `json:"id" gorm:"column:id;type:int(10) unsigned not null AUTO_INCREMENT;primary_key"`
    Title       string `json:"title" gorm:"column:title;type:varchar(250) not null;default:''"`
    Description string `json:"description" gorm:"column:description;type:varchar(250) not null;default:''"`
    Content     string `json:"content" gorm:"column:content;type:longtext default null"`
    ParentId    uint    `json:"parent_id" gorm:"column:parent_id;type:int(10) unsigned not null;default:0;index:idx_parent_id"`
    Status      uint   `json:"status" gorm:"column:status;type:tinyint(1) unsigned not null;default:0;index:idx_status"`
    CreatedTime int64   `json:"created_time" gorm:"column:created_time;type:int(11) not null;default:0;index:idx_created_time"`
    UpdatedTime int64   `json:"updated_time" gorm:"column:updated_time;type:int(11) not null;default:0;index:idx_updated_time"`
    DeletedTime int64   `json:"-" gorm:"column:deleted_time;type:int(11) not null;default:0"`
}

模型字段基本上就是依据 mysql 表的字段一一对应的,并且将字段的信息都标记在构造体字段的标记中。

gorm 的标记也能够省略,省略的话,它默认就是模型构造自字段的蛇形小写模式,如:

type Category struct {
  Id          uint    // 默认字段名是 id
  Title       string  // 默认字段名是 title
  Description string  // 默认字段名是 description
  Content     string  // 默认字段名是 content
  ParentId    uint    // 默认字段名是 parent_id
  Status      uint    // 默认字段名是 status
  CreatedTime int64   // 默认字段名是 created_time
  UpdatedTime int64   // 默认字段名是 updated_time
  DeletedTime int64   // 默认字段名是 deleted_time
}

为了不便 gorm 能够同步迁徙数据库,倡议咱们采纳残缺的写法。这样咱们就能够在有更新字段的时候,应用 AutoMigrate 函数来实现数据迁徙工作,对部署很有帮忙。

留神:主动迁徙仅仅会创立表,短少列和索引,并且不会扭转现有列的类型或删除未应用的列以爱护数据。

article.go 文件的 articles 表 和 article_data 表


type Article struct {Id          uint        `json:"id" gorm:"column:id;type:int(10) unsigned not null AUTO_INCREMENT;primary_key"`
    Title       string      `json:"title" gorm:"column:title;type:varchar(250) not null;default:''"`
    Keywords    string      `json:"keywords" gorm:"column:keywords;type:varchar(250) not null;default:''"`
    Description string      `json:"description" gorm:"column:description;type:varchar(250) not null;default:''"`
    CategoryId  uint        `json:"category_id" gorm:"column:category_id;type:int(10) unsigned not null;default:0;index:idx_category_id"`
    Views       uint        `json:"views" gorm:"column:views;type:int(10) unsigned not null;default:0;index:idx_views"`
    Status      uint        `json:"status" gorm:"column:status;type:tinyint(1) unsigned not null;default:0;index:idx_status"`
    CreatedTime int64       `json:"created_time" gorm:"column:created_time;type:int(11) not null;default:0;index:idx_created_time"`
    UpdatedTime int64       `json:"updated_time" gorm:"column:updated_time;type:int(11) not null;default:0;index:idx_updated_time"`
    DeletedTime int64       `json:"-" gorm:"column:deleted_time;type:int(11) not null;default:0"`
    Category    Category    `json:"category" gorm:"-"`
    ArticleData ArticleData `json:"data"`
}

type ArticleData struct {ArticleId uint   `json:"article_id" gorm:"column:article_id;type:int(10) unsigned not null;primary_key"`
    Content   string `json:"content" gorm:"column:content;type:longtext default null"`
}

因为 articles 表和 article_data 表它们是紧密联系在一起的,因而咱们将这两个模型构造体创立在了同一个文件中,不便咱们查看和治理。

这里阐明一下,Id 字段为自增字段,CategoryId 字段、Views 字段、Status 字段 它们的值都是只有大于零的值,因而咱们定义它们的类型为 uint;而 CreatedTime、UpdatedTime、DeletedTime 字段为工夫戳字段,golang 默认的工夫戳类型是 int64,为了缩小不必要的类型转换,因而咱们定义模型构造体的时候,也将它们定义为 int64 类型,这样不须要再做类型转换就能够间接调用这个值。

这两个模型构造体里,咱们定义了 Article 为 ArticleData 的外键,并且它们就通过外键将两个表绑定在一起了,能够做到数据的完整性。Category 分类表因为不是一对一关系,所以这里咱们在 gorm 中就做疏忽解决。

attachment.go 文件的 attachments 表

type Attachment struct {Id           uint   `json:"id" gorm:"column:id;type:int(10) unsigned not null AUTO_INCREMENT;primaryKey;"`
    FileName     string `json:"file_name" gorm:"column:file_name;type:varchar(100) not null;default:''"`
    FileLocation string `json:"file_location" gorm:"column:file_location;type:varchar(250) not null;default:''"`
    FileSize     int64  `json:"file_size" gorm:"column:file_size;type:bigint(20) unsigned not null;default:0"`
    FileMd5      string `json:"file_md5" gorm:"column:file_md5;type:varchar(32) unique not null;default:''"`
    Width        uint   `json:"width" gorm:"column:width;type:int(10) unsigned not null;default:0"`
    Height       uint   `json:"height" gorm:"column:height;type:int(10) unsigned not null;default:0"`
    Status       uint   `json:"status" gorm:"column:status;type:tinyint(1) unsigned not null;default:0;index:idx_status"`
    CreatedTime  int64    `json:"created_time" gorm:"column:created_time;type:int(11) not null;default:0;index:idx_created_time"`
    UpdatedTime  int64    `json:"updated_time" gorm:"column:updated_time;type:int(11) not null;default:0;index:idx_updated_time"`
    DeletedTime  int64    `json:"-" gorm:"column:deleted_time;type:int(11) not null;default:0"`
    Logo         string `json:"logo" gorm:"-"`
    Thumb        string `json:"thumb" gorm:"-"`
}

Attachment 模型构造体,咱们定义了 Logo 和 Thumb 两个不在 mysql 表中存在的字段,因为 FileLocation 字段寄存的是上传的图片的服务器存储门路,并不一定是浏览器能够间接浏览的文件门路,因为咱们在图片展现的时候,还须要将它转换成可浏览器浏览的门路,图片还有原图和缩略图的辨别,所以咱们定义了 Logo 字段为图片原图可拜访门路,Thumb 为图片缩略图可拜访门路。这两个主动会在 gorm 读出数据后,再通过其余办法来给它赋值。

下面就是咱们博客须要用到的 5 个表的 gorm 模型的定义。模型定义完了之后,咱们就能够对数据进行操作了。下一节咱们将介绍如何操作数据库。

残缺的我的项目示例代码托管在 GitHub 上,须要查看残缺的我的项目代码能够到 github.com/fesiong/goblog 上查看,也能够间接 fork 一份来在下面做批改。

退出移动版