Gorm框架
功能强大的ORM框架(Object Relationship Mapping),拥有很多开源扩展、应用广泛 (和数据库交互)
环境配置
数据库:利用docker desktop 拉取最新的mysql服务器到本地,并设置用户名和密码
## 拉取镜像文件
docker pull mysql:latest
## 运行容器,完成端口映射
docker run --name mysql-server -e MYSQL_ROOT_PASSWORD=rootpassword -p 3306:3306 -d mysql:latest
## 进入容器配置数据库
docker exec -it mysql-server mysql -uroot -prootpassword
## 创建数据库,并设置用户权限
CREATE DATABASE testdb;
CREATE USER 'newuser'@'%' IDENTIFIED BY 'newpassword';
GRANT ALL PRIVILEGES ON testdb.* TO 'newuser'@'%';
FLUSH PRIVILEGES;
EXIT;
## 验证主机能否连接到数据库(在docker desktop 对应mysql-server容器中的exec窗口下执行)
mysql -h 127.0.0.1 -P 3306 -uroot -prootpassword
go环境:下载安装go,确保 GOPATH 和 GOROOT 环境变量已正确设置
然后需要通过powershell/CMD 获取服务驱动,并初始化模块
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
mkdir gorm-example
cd gorm-example
go mod init gorm-example
代码文件
--实现利用gorm增删改查
package main
import (
"log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// 定义 User 模型
type User struct {
ID uint `gorm:"primaryKey;autoIncrement"`
Name string `gorm:"not null"`
Email string `gorm:"unique"`
}
func main() {
// 连接数据库
dsn := "newuser:newpassword@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("failed to connect database: %v", err)
}
// 自动迁移表结构
db.AutoMigrate(&User{})
// 清空表并重置主键
db.Exec("TRUNCATE TABLE users")
// 增加记录
createUser(db, "hello", "world.com")
// 查询记录
getUserByID(db, 1)
// 更新记录
updateUser(db, 1, "not hello")
// 查询记录
getUserByID(db, 1)
// 删除记录
deleteUser(db, 1)
// 查询记录
getUserByID(db, 1)
}
// 增加记录
func createUser(db *gorm.DB, newName string, newEmail string) {
user := User{Name: newName, Email: newEmail}
result := db.Create(&user)
if result.Error != nil {
log.Fatalf("failed to create user: %v", result.Error)
}
log.Printf("User created with ID: %d", user.ID)
}
// 查询记录
func getUserByID(db *gorm.DB, id uint) {
var user User
result := db.First(&user, id)
if result.Error != nil {
log.Fatalf("failed to get user: %v", result.Error)
}
log.Printf("User found: %+v", user)
}
// 更新记录
func updateUser(db *gorm.DB, id uint, newName string) {
var user User
result := db.First(&user, id)
if result.Error != nil {
log.Fatalf("failed to get user: %v", result.Error)
}
user.Name = newName
result = db.Save(&user)
if result.Error != nil {
log.Fatalf("failed to update user: %v", result.Error)
}
log.Printf("User updated: %+v", user)
}
// 删除记录
func deleteUser(db *gorm.DB, id uint) {
var user User
result := db.Delete(&user, id)
if result.Error != nil {
log.Fatalf("failed to delete user: %v", result.Error)
}
log.Printf("User deleted with ID: %d", id)
}
代码输出
go run main.go
PS E:\GoProject\gogogo\demoGorm> go run .\main.go
2024/11/28 10:14:48 User created with ID: 1
2024/11/28 10:14:48 User found: {ID:1 Name:hello Email:world.com}
2024/11/28 10:14:48 User updated: {ID:1 Name:not hello Email:world.com}
2024/11/28 10:14:48 User found: {ID:1 Name:not hello Email:world.com}
2024/11/28 10:14:48 User deleted with ID: 1
2024/11/28 10:14:48 E:/GoProject/gogogo/demoGorm/main.go:63 record not found
[2.173ms] [rows:0] SELECT * FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` LIMIT 1
2024/11/28 10:14:48 failed to get user: record not found
exit status 1
主要参考文档-GORM官方中文书册: gorm.io/zh_CN/docs/…
除去常见的增删改查任务,还可以使用常见的事务、hook等组件来提升操作的完整度
事务,为了确保数据一致性,GORM 会在事务里执行写入操作(创建、更新、删除),而在GORM中也会出现事务的嵌套和手动事务来满足开发的需求,前者好处是可以回滚较大事务内执行的一部分操作,而后者则支持直接调用事务控制方法(commit、rollback),除此之外也提供如SavePoint、RollbackTo等等方法来保证事务回滚的高效
// 事务嵌套
db.Transaction(func(tx *gorm.DB) error {
tx.Create(&user1)
tx.Transaction(func(tx2 *gorm.DB) error {
tx2.Create(&user2)
return errors.New("rollback user2") // Rollback user2
})
return nil
})
// 手动控制事务
// 开始事务
tx := db.Begin()
// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)
// ...
// 遇到错误时回滚事务
tx.Rollback()
// 否则,提交事务
tx.Commit()
hook,在创建、查询、更新、删除等操作之前、之后调用的函数,它会在创建、更新、查询、删除时自动被调用。如果任何回调返回错误,GORM 将停止后续的操作并回滚事务,默认形式func(*gorm.DB) error
// BeforeCreate 钩子,在创建对象之前执行
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
log.Println("BeforeCreate hook called")
return
}
// BeforeUpdate 钩子,在更新对象之前执行
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
log.Println("BeforeUpdate hook called")
return
}
// AfterCreate 钩子,在创建对象之后执行
func (u *User) AfterCreate(tx *gorm.DB) (err error) {
log.Println("AfterCreate hook called")
return
}
// AfterUpdate 钩子,在更新对象之后执行
func (u *User) AfterUpdate(tx *gorm.DB) (err error) {
log.Println("AfterUpdate hook called")
return
}
// AfterDelete 钩子,在删除对象之后执行
func (u *User) AfterDelete(tx *gorm.DB) (err error) {
log.Println("AfterDelete hook called")
return
}
2024/11/28 14:36:20 BeforeCreate hook called
2024/11/28 14:36:20 AfterCreate hook called
2024/11/28 14:36:20 User created with ID: 1
2024/11/28 14:36:20 User found: {ID:1 Name:hello Email:world.com}
2024/11/28 14:36:20 BeforeUpdate hook called
2024/11/28 14:36:20 AfterUpdate hook called
2024/11/28 14:36:20 User updated: {ID:1 Name:not hello Email:world.com}
2024/11/28 14:36:20 User found: {ID:1 Name:not hello Email:world.com}
2024/11/28 14:36:20 AfterDelete hook called
2024/11/28 14:36:20 User deleted with ID: 1