做视频网站需要什么空间吗,推广普通话的标语,建设银行住房公积网站,备案网站建设承诺书简介
1.什么是orm
ORM全称是:Object Relational Mapping(对象关系映射)#xff0c;其主要作用是在编程中#xff0c;把面向对象的概念跟数据库中表的概念对应起来。举例来说就是#xff0c;我定义一个对象#xff0c;那就对应着一张表#xff0c;这个对象的实例#xf…简介
1.什么是orm
ORM全称是:Object Relational Mapping(对象关系映射)其主要作用是在编程中把面向对象的概念跟数据库中表的概念对应起来。举例来说就是我定义一个对象那就对应着一张表这个对象的实例就对应着表中的一条记录。 对于数据来说最重要最常用的是表:表中有列, orm就是将一张表映射成一个类表中的列映射成类中的一个类。java 、python但是针对go语言而言struct就是列如何映射是因为列可以映射成struct中的类型int-int,但是有另一个问题?就是数据库中的列具备很好的描述性但是struct有tag。 执行sql需要我们有足够的sql语句基础、需要我们懂得不同的数据的sql 2.orm的优缺点
优点: 提高了开发效率。 屏蔽sql细节。可以自动对实体Entity对象与数据库中的Table进行字段与属性的映射;不用直接sQL编码 屏闭各种数据库之间的差异
缺点:
orm会牺牲程序的执行效率和会固定思维模式太过依赖orm会导致sql理解不够对于固定的orm依赖过重导致切换到其他的orm代价高
如何正确看待orm和sql之间的关系
sql为主orm为辅orm主要目的是为了增加代码可维护性和开发效率
教程
导入gorm
go get -u gorm.io/gorm
go get gorm.io/driver/mysql #选择自己相应的数据库gorm连接数据库
有关gorm连接数据库的url格式参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
字段(对照示例,dsn变量)示例值用户名root密码123123协议tcpip127.0.0.1端口3306数据库名gorm_test编码utf8mb4
package main
import (fmtgorm.io/driver/mysqlgorm.io/gorm
)func main() {dsn : root:123123tcp(127.0.0.1:3306)/gorm_test?charsetutf8mb4parseTimeTruelocLocaldb, err : gorm.Open(mysql.Open(dsn), gorm.Config{})if err ! nil{fmt.Println(err.Error())}
}AutoMigrate功能
AutoMigrate 是 GORM 中一个非常方便的功能它可以根据你定义的 Go 结构体模型自动创建或更新数据库表结构使其与模型相匹配。
当你定义了一个 Go 结构体作为数据库的模型时通过 AutoMigrate 方法GORM 可以根据该结构体自动生成对应的数据库表。如果表已存在则它会检查表的结构是否与模型相匹配如果有必要会自动进行表结构的迁移或修改以确保其与模型一致。
这个功能非常适合在开发过程中对数据库模型进行调整和迭代时使用它可以简化数据库迁移的过程让你专注于代码逻辑的开发而不用手动管理数据库表结构的变化。
示例代码如下
package mainimport (gorm.io/driver/mysqlgorm.io/gorm
)type Product struct {ID uint gorm:primaryKey;default:auto_random()Code stringPrice int
}func main() {// 连接数据库dsn : root:123123tcp(127.0.0.1:3306)/gorm_test?charsetutf8mb4parseTimeTruelocLocal// 替换上面的信息为你的数据库用户名、密码和数据库名db, err : gorm.Open(mysql.Open(dsn), gorm.Config{})if err ! nil {panic(Failed to connect to database)}// 自动创建或更新表结构db.AutoMigrate(Product{})
}
在这个例子中Product 结构体作为数据库的模型使用 AutoMigrate 方法来确保数据库中存在与该模型相对应的表。如果数据库中没有名为 “Product” 的表Product 结构体默认会映射到 “Product” 表那么该方法将会创建一个。如果表已经存在但与模型的定义不匹配它会尝试修改表结构使其与模型匹配。 最基本的CURD
要点总结:
变量名首字母记得大写如果是多单词(大驼峰):在数据库中命名会转化成下划线如果没有继承gorm.Model,进行删除操作会真正的删除,但如果继承了,gorm会添加几个额外的字段进行标记,实行逻辑删除在数据库中所有的字段名都会转化成小写在生成数据库时候,会对struct name进行复数转化,也就是大写
package mainimport (gorm.io/gormgorm.io/driver/sqlite
)type Product struct {gorm.ModelCode stringPrice uint
}func main() {db, err : gorm.Open(sqlite.Open(test.db), gorm.Config{})if err ! nil {panic(failed to connect database)}// 迁移 schemadb.AutoMigrate(Product{})// Createdb.Create(Product{Code: D42, Price: 100})// Readvar product Productdb.First(product, 1) // 根据整型主键查找db.First(product, code ?, D42) // 查找 code 字段值为 D42 的记录// Update - 将 product 的 price 更新为 200db.Model(product).Update(Price, 200)// Update - 更新多个字段db.Model(product).Updates(Product{Price: 200, Code: F42}) // 仅更新非零值字段db.Model(product).Updates(map[string]interface{}{Price: 200, Code: F42})// Delete - 删除 productdb.Delete(product, 1)
}设置空值
在gorm中,对字段进行更新操作不能设置0值,否则会被屏蔽掉(不会修改),那么怎么才能设置0值呢
导入database/sql包在包中设置了很多sql.NullXXXX的结构体,我们只需要**将第一个字段设置为0值,**第二个字段设置为true即可或者使用指针,指向nil即可
声明模型
约定
GORM 倾向于约定优于配置 默认情况下GORM 使用 ID 作为主键使用结构体名的 蛇形复数 作为表名字段名的 蛇形 作为列名并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间
如果您遵循 GORM 的约定您就可以少写的配置、代码。 如果约定不符合您的实际要求GORM 允许你配置它们
gorm.Model
GORM 定义一个 gorm.Model 结构体其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt
// gorm.Model 的定义
type Model struct {ID uint gorm:primaryKeyCreatedAt time.TimeUpdatedAt time.TimeDeletedAt gorm.DeletedAt gorm:index
}您可以将它嵌入到您的结构体中以包含这几个字段详情请参考 嵌入结构体
高级选项
字段级权限控制
可导出的字段在使用 GORM 进行 CRUD 时拥有全部的权限此外GORM 允许您用标签控制字段级别的权限。这样您就可以让一个字段的权限是只读、只写、只创建、只更新或者被忽略 注意 使用 GORM Migrator 创建表时不会创建被忽略的字段 type User struct {Name string gorm:-:create // 允许读和创建Name string gorm:-:update // 允许读和更新Name string gorm:- // 允许读和写创建和更新Name string gorm:-:false // 允许读禁止写Name string gorm:- // 只读除非有自定义配置否则禁止写Name string gorm:-;-:create // 允许读和写Name string gorm:-:false;-:create // 仅创建禁止从 db 读Name string gorm:- // 通过 struct 读写会忽略该字段Name string gorm:-:all // 通过 struct 读写、迁移会忽略该字段Name string gorm:-:migration // 通过 struct 迁移会忽略该字段
}创建/更新时间追踪纳秒、毫秒、秒、Time
GORM 约定使用 CreatedAt、UpdatedAt 追踪创建/更新时间。如果您定义了这种字段GORM 在创建、更新时会自动填充 当前时间
要使用不同名称的字段您可以配置 autoCreateTime、autoUpdateTime 标签。
如果您想要保存 UNIX毫/纳秒时间戳而不是 time您只需简单地将 time.Time 修改为 int 即可
type User struct {CreatedAt time.Time // 在创建时如果该字段值为零值则使用当前时间填充UpdatedAt int // 在创建时该字段值为零值或者在更新时使用当前时间戳秒数填充Updated int64 gorm:autoUpdateTime:nano // 使用时间戳纳秒数填充更新时间Updated int64 gorm:autoUpdateTime:milli // 使用时间戳毫秒数填充更新时间Created int64 gorm:autoCreateTime // 使用时间戳秒数填充创建时间
}嵌入结构体
对于匿名字段GORM 会将其字段包含在父结构体中例如
type User struct {gorm.ModelName string
}
// 等效于
type User struct {ID uint gorm:primaryKeyCreatedAt time.TimeUpdatedAt time.TimeDeletedAt gorm.DeletedAt gorm:indexName string
}对于正常的结构体字段你也可以通过标签 embedded 将其嵌入例如
type Author struct {Name stringEmail string
}type Blog struct {ID intAuthor Author gorm:embeddedUpvotes int32
}
// 等效于
type Blog struct {ID int64Name stringEmail stringUpvotes int32
}并且您可以使用标签 embeddedPrefix 来为 db 中的字段名添加前缀例如
type Blog struct {ID intAuthor Author gorm:embedded;embeddedPrefix:author_Upvotes int32
}
// 等效于
type Blog struct {ID int64AuthorName stringAuthorEmail stringUpvotes int32
}字段标签
声明 model 时tag 是可选的GORM 支持以下 tag tag 名大小写不敏感但建议使用 camelCase 风格
标签名说明column指定 db 列名type列数据类型推荐使用兼容性好的通用类型例如所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用例如not null、size, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时它需要是完整的数据库数据类型如MEDIUMINT UNSIGNED not NULL AUTO_INCREMENTserializer指定将数据序列化或反序列化到数据库中的序列化器, 例如: serializer:json/gob/unixtimesize定义列数据类型的大小或长度例如 size: 256primaryKey将列定义为主键unique将列定义为唯一键default定义列的默认值precision指定列的精度scale指定列大小not null指定列为 NOT NULLautoIncrement指定列为自动增长autoIncrementIncrement自动步长控制连续记录之间的间隔embedded嵌套字段embeddedPrefix嵌入字段的列名前缀autoCreateTime创建时追踪当前时间对于 int 字段它会追踪时间戳秒数您可以使用 nano/milli 来追踪纳秒、毫秒时间戳例如autoCreateTime:nanoautoUpdateTime创建/更新时追踪当前时间对于 int 字段它会追踪时间戳秒数您可以使用 nano/milli 来追踪纳秒、毫秒时间戳例如autoUpdateTime:milliindex根据参数创建索引多个字段使用相同的名称则创建复合索引查看 索引 获取详情uniqueIndex与 index 相同但创建的是唯一索引check创建检查约束例如 check:age 13查看 约束 获取详情-设置字段写入的权限 -:create 只创建、-:update 只更新、-:false 无写入权限、- 创建和更新权限-设置字段读的权限-:false 无读权限-忽略该字段- 表示无读写-:migration 表示无迁移权限-:all 表示无读写迁移权限comment迁移时为字段添加注释