大型综合新闻门户网站织梦模板,太原做网页软件,深圳注册公司地址怎么解决,WordPress主题zeroGORM 是 Go 语言中一个非常流行的 ORM#xff08;对象关系映射#xff09;库#xff0c;它允许开发者通过结构体来定义数据库表结构#xff0c;并提供了丰富的 API 来操作数据库。 安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite表结构
在 gorm 中定义表结…GORM 是 Go 语言中一个非常流行的 ORM对象关系映射库它允许开发者通过结构体来定义数据库表结构并提供了丰富的 API 来操作数据库。 安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite表结构
在 gorm 中定义表结构通常是通过定义一个结构体struct来完成的其中每个字段对应数据库表中的列。
以下是一个使用 GORM 定义的简单用户表结构的例子
package mainimport (gorm.io/gormgorm.io/dialects/mysql
)// User 定义了用户的表结构
type User struct {// gorm.Model 包含了一些默认字段ID, CreatedAt, UpdatedAt, DeletedAtgorm.Model// 用户名设置为唯一且不能为空Name string gorm:column:user_name;type:varchar(50);unique;not null// 手机号设置为唯一且不能为空Phone string gorm:type:varchar(20);unique;not null// 密码存储为二进制大对象Password []byte gorm:type:blob json:-
}func main() {// 连接数据库dsn : user:passwordtcp(127.0.0.1:3306)/dbname?charsetutf8mb4parseTimeTruelocLocaldb, err : gorm.Open(mysql.Open(dsn), gorm.Config{})if err ! nil {panic(failed to connect database)}// 自动迁移模式 - 根据结构体创建或更新表结构db.AutoMigrate(User{})
}在这个例子中
gorm.Model 是一个便捷的结构体包含了 ID, CreatedAt, UpdatedAt, DeletedAt 字段。Name 和 Phone 字段设置了数据库列名、类型、是否唯一以及是否可以为空。Password 字段被设置为 blob 类型并且不包含在 JSON 序列化中。dsn (Data Source Name) 是用来连接 MySQL 数据库的字符串。db.AutoMigrate(User{}) 会自动根据 User 结构体创建或更新对应的数据库表结构。
在 GORM 中单表操作包括创建、查询、更新和删除记录。以下是一些基本的单表操作示例
单表操作
创建记录
创建记录通常使用 Create 方法。
// 创建一个新的 User 实例
user : User{Name: 张三, Age: 30, Email: zhangsanexample.com}
// 使用 Create 方法创建记录
result : db.Create(user)
// 检查错误
if result.Error ! nil {panic(result.Error)
}
// 输出插入后的用户 ID
fmt.Printf(插入后的用户 ID: %d\n, user.ID)查询记录
查询记录可以使用 First, Find, Take, Last 等方法。
查询第一个匹配的记录
// 查询第一个用户
var user User
result : db.First(user)
if result.Error ! nil {panic(result.Error)
}
fmt.Printf(查询到的用户: %v\n, user)查询所有记录
// 查询所有用户
var users []User
result : db.Find(users)
if result.Error ! nil {panic(result.Error)
}
fmt.Printf(查询到的用户列表: %v\n, users)条件查询
// 查询年龄为 30 的用户
var user User
result : db.Where(age ?, 30).First(user)
if result.Error ! nil {panic(result.Error)
}
fmt.Printf(查询到的用户: %v\n, user)更新记录
更新记录通常使用 Update 或 Updates 方法。
更新单个字段
// 更新第一个用户的年龄
result : db.Model(User{}).Where(id ?, 1).Update(age, 31)
if result.Error ! nil {panic(result.Error)
}
fmt.Printf(更新影响的行数: %d\n, result.RowsAffected)更新多个字段
// 更新第一个用户的年龄和邮箱
result : db.Model(User{}).Where(id ?, 1).Updates(User{Age: 32, Email: zhangsan_newexample.com})
if result.Error ! nil {panic(result.Error)
}
fmt.Printf(更新影响的行数: %d\n, result.RowsAffected)删除记录
删除记录使用 Delete 方法。
// 删除 ID 为 1 的用户
result : db.Delete(User{}, 1)
if result.Error ! nil {panic(result.Error)
}
fmt.Printf(删除影响的行数: %d\n, result.RowsAffected)软删除
如果你的模型包含了 gorm.DeletedAt字段该字段也被包含在gorm.Model中那么该模型将会自动获得软删除的能力
当调用Delete时GORM并不会从数据库中删除该记录而是将该记录的DeleteAt设置为当前时间而后的一般查询方法将无法查找到此条记录。
查找被删除的记录
DB.Unscoped().Find(users)永久删除
db.Unscoped().Delete(user)单标高级查询
条件查询
Where 子句
// 查询年龄大于 30 的用户
var users []User
db.Where(age ?, 30).Find(users)Struct Map 条件
// 使用结构体作为条件
db.Where(User{Name: 张三, Age: 30}).Find(users)
// 使用 Map 作为条件
db.Where(map[string]interface{}{name: 张三, age: 30}).Find(users)Not 条件
// 查询年龄不等于 30 的用户
db.Not(age ?, 30).Find(users)Or 条件
// 查询年龄大于 30 或者名字是李四的用户
db.Where(age ?, 30).Or(name ?, 李四).Find(users)内联条件
// 内联条件查询
db.Find(users, age ?, 30)Select 子句
// 仅查询特定字段
db.Select(name, age).Find(users)Order By
// 根据年龄排序
db.Order(age desc).Find(users)Limit Offset
// 限制返回结果的数量并设置偏移量
db.Limit(10).Offset(20).Find(users)Count
// 计算符合条件的记录数量
var count int64
db.Where(age ?, 20).Model(User{}).Count(count)Group By Having
// 分组并使用 Having 子句
db.Model(User{}).Select(name, sum(age) as total_age).Group(name).Having(total_age ?, 100).Find(users)Joins
// 内连接查询
db.Joins(JOIN orders ON orders.user_id users.id).Where(orders.status ?, paid).Find(users)Scopes
// 定义一个 Scope
func AgeGreaterThan(age int) func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {return db.Where(age ?, age)}
}
// 使用 Scope 查询
db.Scopes(AgeGreaterThan(30)).Find(users)Pluck
// 提取单个列的值
var ages []int
db.Model(User{}).Pluck(age, ages)Scan
// 将查询结果映射到不同的结构体
type Result struct {Name stringAge int
}
var result Result
db.Model(User{}).Select(name, age).Where(id ?, 1).Scan(result)多表关系与操作
在 GORM 中处理多表关系和多表操作是非常直观的它支持多种关系类型如一对一、一对多、多对多等
定义多表关系
一对一关系 (One-to-One)
假设我们有一个 User 模型和一个 Profile 模型每个用户只有一个个人资料。
type User struct {gorm.ModelName stringProfile Profile
}type Profile struct {gorm.ModelUserID uintBio string
}这里 Profile 表通过 UserID 字段与 User 表关联。
一对多关系 (One-to-Many)
假设我们有一个 User 模型和一个 Order 模型每个用户可以有多个订单。
type User struct {gorm.ModelName stringOrders []Order
}type Order struct {gorm.ModelUserID uintAmount float64
}这里 Order 表通过 UserID 字段与 User 表关联。
多对多关系 (Many-to-Many)
假设我们有一个 User 模型和一个 Language 模型每个用户可以掌握多种语言每种语言也可以被多个用户掌握。
type User struct {gorm.ModelName stringLanguages []Language gorm:many2many:user_languages;
}type Language struct {gorm.ModelName string
}这里使用了一个中间表 user_languages 来存储 User 和 Language 之间的关系。
多表操作
创建关联记录
对于一对一和一对多的关系你可以直接创建并保存关联的模型
// 创建用户及其个人资料
func createUserWithProfile(db *gorm.DB) {db.Create(User{Name: John Doe,Profile: Profile{Bio: Hello, Im John},})
}// 创建用户及其订单
func createUserWithOrders(db *gorm.DB) {db.Create(User{Name: Jane Doe,Orders: []Order{{Amount: 100.0},{Amount: 200.0},},})
}对于多对多的关系你需要先创建两边的模型然后再建立它们之间的关系
// 创建用户及其语言
func createUserWithLanguages(db *gorm.DB) {user : User{Name: Alice}languages : []Language{{Name: English}, {Name: Spanish}}// 先创建用户和语言db.Create(user)for i : range languages {db.Create(languages[i])}// 建立关系db.Model(user).Association(Languages).Append(languages)
}查询关联数据
GORM 支持预加载Preloading来一次性加载关联的数据
// 预加载用户的个人资料
func getUserWithProfile(db *gorm.DB, userID uint) {var user Userdb.Preload(Profile).First(user, userID)log.Printf(User: %v, Profile: %v, user, user.Profile)
}// 预加载用户的订单
func getUserWithOrders(db *gorm.DB, userID uint) {var user Userdb.Preload(Orders).First(user, userID)log.Printf(User: %v, Orders: %v, user, user.Orders)
}// 预加载用户的语言
func getUserWithLanguages(db *gorm.DB, userID uint) {var user Userdb.Preload(Languages).First(user, userID)log.Printf(User: %v, Languages: %v, user, user.Languages)
}更新关联数据
更新关联数据通常涉及添加或移除关联项
// 添加新的语言给用户
func addUserLanguage(db *gorm.DB, userID uint, languageID uint) {var user Userdb.First(user, userID)db.Model(user).Association(Languages).Append(Language{Model: gorm.Model{ID: languageID}})
}// 从用户中移除一种语言
func removeUserLanguage(db *gorm.DB, userID uint, languageID uint) {var user Userdb.First(user, userID)db.Model(user).Association(Languages).Delete(Language{Model: gorm.Model{ID: languageID}})
}删除关联数据
删除关联数据时可以选择级联删除或只是删除关联本身
// 删除用户及其所有订单
func deleteUserAndOrders(db *gorm.DB, userID uint) {db.Delete(User{}, userID)
}// 只删除用户的某个订单
func deleteOrder(db *gorm.DB, orderID uint) {db.Delete(Order{}, orderID)
}// 删除用户及其所有语言关联
func deleteUserAndLanguages(db *gorm.DB, userID uint) {db.Delete(User{}, userID)
}事务
在 GORM 中事务用于确保数据库操作的原子性这意味着要么所有操作都成功执行要么在遇到错误时所有操作都不会对数据库产生影响。以下是如何在 GORM 中使用事务的示例
开始事务
在 GORM 中你可以使用 Begin 方法来开始一个新的事务。
tx : db.Begin() // 开始事务在事务中执行操作
在事务中你可以执行任何你通常会在 GORM 中执行的操作例如创建、更新、删除等。
user : User{Name: 张三, Age: 30}
if err : tx.Create(user).Error; err ! nil {tx.Rollback() // 遇到错误时回滚事务return err
}
post : Post{Title: 事务测试, Content: 这是一个事务中的帖子, UserID: user.ID}
if err : tx.Create(post).Error; err ! nil {tx.Rollback() // 遇到错误时回滚事务return err
}提交事务
如果所有操作都成功执行你可以调用 Commit 方法来提交事务。
if err : tx.Commit().Error; err ! nil {return err // 提交事务时出错
}回滚事务
如果在事务中的任何操作失败你应该调用 Rollback 方法来回滚所有更改。
if err : tx.Rollback().Error; err ! nil {return err // 回滚事务时出错
}使用 Transaction 方法
GORM 还提供了一个 Transaction 方法它接受一个函数作为参数这个函数将在事务的上下文中执行。如果函数返回错误事务将自动回滚如果没有错误事务将自动提交。
err : db.Transaction(func(tx *gorm.DB) error {user : User{Name: 李四, Age: 28}if err : tx.Create(user).Error; err ! nil {return err // 返回任何错误都会回滚事务}post : Post{Title: 另一个事务测试, Content: 这是另一个事务中的帖子, UserID: user.ID}if err : tx.Create(post).Error; err ! nil {return err // 返回任何错误都会回滚事务}return nil // 返回 nil 提交事务
})
if err ! nil {// 事务回滚处理错误
}使用 Transaction 方法可以简化事务的处理因为它自动处理了提交和回滚的逻辑。