• golang gorm 模型定义与tag字段详解


    gorm

    orm 概念

    对象关系映射,可以通过操作实际数据结构,去操作具体的数据库表。减少一定工作量。更方便入手编程操作数据库, 减少一定SQL开发量

    为什么使用orm

    • 规范一致,能调用的接口orm库提供
    • 减少一定工作量,建表,建库,修改表结构等(但一般生成环境都会直接指向对应ddl脚本),直接修改对象即可同步到数据库。
    • 对于一些开源系统,通用系统部署方便,只需要提供数据库
    • 解耦数据库和数据层,更加方便更换数据库引擎。

    为什么不建议使用orm

    • 数据层不能因为使用orm而减少
    • 大量的反射,导致程序性能会比原生SQL慢(但不同orm库有对应优化。例如gorm采用预编译的机制,提前将一些对象字段的SQL编译好,生成SQL时直接通过缓存的方式查找出来,减少反射耗时)
    • orm提供了大量表关系接口,这些接口在数据流较少的情况时影响不大,当数据量大的时候是致命的
    • 没有SQL基础的开发,大概率不能正确使用orm

    比如做表链接时,查询会很慢。一般是进行两次查询,然后业务内进行处理。(数据量大的时候绝大多数情况都会比直接一次表链接快)

    PS: 表链接操作,不建议用orm(数据量少情况下也可以用)

    gorm Model定义与tag使用

    模型定义

    使用标准的go struct。

    type User struct { 
        ID uint Name 
        string Email *string 
        Age uint8 Birthday *time.Time 
        MemberNumber sql.NullString 
        ActivatedAt sql.NullTime 
        CreatedAt time.Time 
        UpdatedAt time.Time 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    GORM 倾向于约定优于配置 默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间如果遵循 GORM 的约定,可以少写的配置、代码。 如果约定不符合实际要求,则只能通过配置实现。

    go Model
    package gorm
    
    import "time"
    
    // Model a basic GoLang struct which includes the following fields: ID, CreatedAt, UpdatedAt, DeletedAt
    // It may be embedded into your model or you may build your own model without it
    //    type User struct {
    //      gorm.Model
    //    }
    type Model struct {
    	ID        uint `gorm:"primarykey"`
    	CreatedAt time.Time
    	UpdatedAt time.Time
    	DeletedAt DeletedAt `gorm:"index"`
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    官方建议是直接内嵌到自己的结构体中

    字段tag
    tagdesc
    column指定 db 列名
    type列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes
    serializer指定序列化和反序列化方式,例如:json/gob/unixtime
    size指定列大小,例如:size:256
    primaryKey指定列为主键
    unique指定列为唯一
    default指定列的默认值
    precision指定列的宽度,例如:浮点数float(7,2),其中precision为7,表示不包括小数点在内的列宽,即整数部分加小数部分的总长度
    scale指定列中小数部分的宽度,例如:浮点数float(7,2),其中scale为2,表示浮点数的精度,多余的小数位数会被四舍五入
    not null指定列为 NOT NULL
    autoIncrement指定列为自动增长
    autoIncrementIncrement指定列的自增步长
    embedded嵌套字段
    embeddedPrefix嵌入字段的列名前缀
    autoCreateTime创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano
    autoUpdateTime创建/更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli
    index根据参数创建索引,多个字段使用相同的名称则创建复合索引
    uniqueIndex与 index 相同,但创建的是唯一索引
    check创建检查约束,例如 check:age > 13
    <-设置字段写入的权限, <-:create 只创建、<-:update 只更新、<-:false无写入权限、<- 创建和更新权限
    ->设置字段读的权限,->:false 无读权限
    -忽略该字段,- 无读写权限
    comment添加字段描述信息
    简单案例
    package _case
    
    import "gorm.io/gorm"
    
    func init() {
        DB.Migrator().AutoMigrate(Teacher{}, Course{})
    }
    type Roles []string
    
    type Teacher struct {
        gorm.Model
        Name     string   `gorm:"size:256"`
        Email    string   `gorm:"size:256"`
        Salary   float64  `gorm:"scale:2;precision:7"`   // 指定小数部分宽度为2,列宽度为7. 列宽:【整数部分+小数部分的总长度】【不含小数点】
        Age      uint8    `gorm:"check:age>30"`
        Birthday int64    `gorm:"serializer:unixtime;type:time"`  // 反序列化方式 unixtime, 类型为time
        Roles    Roles    `gorm:"serializer:json"`
        JobInfo  Job      `gorm:"embedded;embeddedPrefix:job_"`   // 嵌套字段, 嵌入字段的列名前缀job_
        JobInfo2 Job      `gorm:"type:bytes;serializer:gob"`      // 字节流类型,gob反序列化,go自己的序列化方法,跨语言项目的时候,不建议用
    }
    
    type Job struct {
        Title    string
        Location string
    }
    
    type Course struct {
        gorm.Model
        Name   string  `gorm:"size:256"`
        Price  float64 `gorm:"scale:2;precision:7"`
        UserID uint    `gorm:"type:int"`
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    应用建议

    实际生产中,基本上都是用ddl脚本去建数据库,或者用一些数据迁移框架去移植表(配合ddl脚本) 很少用gorm去做ddl操作,都是仅用来做增删改查事务 等非ddl操作。

  • 相关阅读:
    数据指标是什么?简单聊聊企业的数据指标体系
    【车载开发系列】UDS诊断---通信控制($0x28)
    在线文本数字识别列表求和工具
    网络模型(DeepLab, DeepLabv3)
    vue cli npm run build打生产环境包报错Cannot read property ‘pop‘ of undefined
    gRPC入门学习之旅(十)
    跳表C语言
    脉冲神经网络原理及应用,脉冲神经网络项目名称
    李宏毅深度学习--《Unsupervised Learning: Word Embedding》
    免费好用的Mac电脑磁盘清理工具CleanMyMac
  • 原文地址:https://blog.csdn.net/qq_43058348/article/details/133686406