全网最简 Gorm 教程 | Gorm 模型定义

发布时间:2026/7/3 1:04:33

全网最简 Gorm 教程 | Gorm 模型定义 模型定义前面入门案例中我们定义了User结构体用来和数据表users做映射User结构体我们称之为数据模型在gorm框架中操作数据库需要预先定义模型。底层都是使用的golang的database标准库利用反射原理执行读写操作时将结构体翻译为sql语句并将结果转化为对应的模型。1. 模型定义假设有一个商品表CREATETABLEgoods(idint(10)unsignedNOTNULLAUTO_INCREMENTCOMMENT自增ID商品Id,namevarchar(30)NOTNULLCOMMENT商品名,pricedecimal(10,2)unsignedNOTNULLCOMMENT商品价格,type_idint(10)unsignedNOTNULLCOMMENT商品类型Id,createtimeint(10)NOTNULLDEFAULT0COMMENT创建时间,PRIMARYKEY(id))ENGINEInnoDBDEFAULTCHARSETutf8mb4将上述表翻译为模型后如下typeGoodstruct{Idint//表字段名为idNamestring//表字段名为namePricefloat64//表字段名为priceTypeIdint//表字段名为type_idCreateTimeint64gorm:column:createtime//表字段名为createtime}默认gorm对struct字段名使用Snake Case命名风格转换成mysql表字段名(需要转换成小写字母)。Snake Case命名风格就是各个单词之间用下划线_分隔例如 CreateTime的Snake Case风格命名为create_time同时默认情况下使用ID做为其主键使用结构体名称的Snake Case风格的复数形式做为表名使用CreatedAt、UpdatedAt字段追踪创建、更新时间。2. 模型标签标签定义gorm:标签内容标签定义部分多个标签定义可以使用分号;分隔gorm常用标签如下标签说明例子column指定列名gorm:column:createtimeprimaryKey指定主键gorm:column:id; PRIMARY_KEY-忽略字段gorm:-可以忽略struct字段被忽略的字段不参与gorm的读写操作其他的可以查看官方文档https://gorm.io/zh_CN/docs/models.html#embedded_struct3. 表名映射复数表名比如结构体User默认的表名为users实现Tabler接口 TableName不支持动态变化它会被缓存下来以便后续使用。typeTablerinterface{TableName()string}// TableName 会将 User 的表名重写为 profilesfunc(User)TableName()string{returnprofiles}动态表名使用ScopesfuncUserTable(user User)func(tx*gorm.DB)*gorm.DB{returnfunc(tx*gorm.DB)*gorm.DB{ifuser.Admin{returntx.Table(admin_users)}returntx.Table(users)}}db.Scopes(UserTable(user)).Create(user)临时表名db.Table(deleted_users)4. ModelGORM 定义一个gorm.Model结构体其包括字段ID、CreatedAt、UpdatedAt、DeletedAt// gorm.Model 的定义typeModelstruct{IDuintgorm:primaryKeyCreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAtgorm:index}GORM 约定使用CreatedAt、UpdatedAt追踪创建/更新时间。如果定义了这种字段GORM 在创建、更新时会自动填充当前时间。要使用不同名称的字段您可以配置 autoCreateTime、autoUpdateTime 标签如果想要保存 UNIX毫/纳秒时间戳而不是 time只需简单地将 time.Time 修改为 int 即可。例子typeUserstruct{CreatedAt time.Time// 默认创建时间字段 在创建时如果该字段值为零值则使用当前时间填充UpdatedAtint// 默认更新时间字段 在创建时该字段值为零值或者在更新时使用当前时间戳秒数填充Updatedint64gorm:autoUpdateTime:nano// 自定义字段 使用时间戳填纳秒数充更新时间Updatedint64gorm:autoUpdateTime:milli//自定义字段 使用时间戳毫秒数填充更新时间Createdint64gorm:autoCreateTime//自定义字段 使用时间戳秒数填充创建时间}可以将它嵌入到您的结构体中以包含这几个字段比如typeUserstruct{gorm.Model Namestring}// 等效于typeUserstruct{IDuintgorm:primaryKeyCreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAtgorm:indexNamestring}对于正常的结构体字段你也可以通过标签embedded将其嵌入例如typeAuthorstruct{NamestringEmailstring}typeBlogstruct{IDintAuthor Authorgorm:embeddedUpvotesint32}// 等效于typeBlogstruct{IDint64NamestringEmailstringUpvotesint32}可以使用标签embeddedPrefix来为 db 中的字段名添加前缀例如typeBlogstruct{IDintAuthor Authorgorm:embedded;embeddedPrefix:author_Upvotesint32}// 等效于typeBlogstruct{IDint64AuthorNamestringAuthorEmailstringUpvotesint32}5. 数据库连接GORM 官方支持的数据库类型有 MySQL, PostgreSQL, SQlite, SQL Server连接数据库主要是两个步骤配置DSN (Data Source Name)使用gorm.Open连接数据库5.1 DSNgorm库使用dsn作为连接数据库的参数dsn翻译过来就叫数据源名称用来描述数据库连接信息。一般都包含数据库连接地址账号密码之类的信息。格式[username[:password]][protocol[(address)]]/dbname[?param1value1...paramNvalueN]mysql的dsn的一些例子//mysql dsn格式//涉及参数://username 数据库账号//password 数据库密码//host 数据库连接地址可以是Ip或者域名//port 数据库端口//Dbname 数据库名username:passwordtcp(host:port)/Dbname?charsetutf8parseTimeTruelocLocal//填上参数后的例子//username root//password 123456//host localhost//port 3306//Dbname gorm//后面K/V键值对参数含义为// charsetutf8 客户端字符集为utf8// parseTimetrue 支持把数据库datetime和date类型转换为golang的time.Time类型// locLocal 使用系统本地时区root:123456tcp(localhost:3306)/gorm?charsetutf8parseTimeTruelocLocal//gorm 设置mysql连接超时参数//开发的时候经常需要设置数据库连接超时参数gorm是通过dsn的timeout参数配置//例如设置10秒后连接超时timeout10s//下面是完成的例子root:123456tcp(localhost:3306)/gorm?charsetutf8parseTimeTruelocLocaltimeout10s//设置读写超时时间// readTimeout - 读超时时间0代表不限制// writeTimeout - 写超时时间0代表不限制root:123456tcp(localhost:3306)/gorm?charsetutf8parseTimeTruelocLocaltimeout10sreadTimeout30swriteTimeout60s要支持完整的 UTF-8 编码您需要将charsetutf8更改为charsetutf8mb45.2 连接数据库import(gorm.io/driver/mysqlgorm.io/gorm)funcmain(){// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn:user:passtcp(127.0.0.1:3306)/dbname?charsetutf8mb4parseTimeTruelocLocaldb,err:gorm.Open(mysql.Open(dsn),gorm.Config{})}MySQL 驱动程序提供了 一些高级配置 可以在初始化过程中使用例如db,err:gorm.Open(mysql.New(mysql.Config{DSN:gorm:gormtcp(127.0.0.1:3306)/gorm?charsetutf8parseTimeTruelocLocal,// DSN data source nameDefaultStringSize:256,// string 类型字段的默认长度DisableDatetimePrecision:true,// 禁用 datetime 精度MySQL 5.6 之前的数据库不支持DontSupportRenameIndex:true,// 重命名索引时采用删除并新建的方式MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引DontSupportRenameColumn:true,// 用 change 重命名列MySQL 8 之前的数据库和 MariaDB 不支持重命名列SkipInitializeWithVersion:false,// 根据当前 MySQL 版本自动配置}),gorm.Config{})GORM 允许通过DriverName选项自定义 MySQL 驱动例如import(_example.com/my_mysql_drivergorm.io/driver/mysqlgorm.io/gorm)db,err:gorm.Open(mysql.New(mysql.Config{DriverName:my_mysql_driver,DSN:gorm:gormtcp(localhost:9910)/gorm?charsetutf8parseTimeTruelocLocal,// data source name, 详情参考https://github.com/go-sql-driver/mysql#dsn-data-source-name}),gorm.Config{})5.3 调试模式db.Debug()5.4 连接池配置sqlDB,_:db.DB()//设置数据库连接池参数sqlDB.SetMaxOpenConns(100)//设置数据库连接池最大连接数sqlDB.SetMaxIdleConns(20)//连接池最大允许的空闲连接数如果没有sql任务需要执行的连接数大于20超过的连接会被连接池关闭

相关新闻