feat(auth): 添加完整的用户认证API项目
- 实现用户注册、登录、JWT令牌认证功能 - 集成Gin、GORM、Viper、Zap等框架 - 添加密码加密、数据库操作、中间件等完整功能 - 配置多环境支持、日志轮转、CORS处理 - 创建完整的项目结构和配置文件体系
This commit is contained in:
71
Web开发/03go-gorm-demo/association_methods.go
Normal file
71
Web开发/03go-gorm-demo/association_methods.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Orders []Order
|
||||
//}
|
||||
//
|
||||
//type Order struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// UserID uint
|
||||
// Product string `gorm:"size:100"`
|
||||
// Amount int
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{}, &Order{})
|
||||
|
||||
//user := User{Name: "Alice"}
|
||||
//db.Create(&user)
|
||||
|
||||
//查询用户根据名称
|
||||
var user User
|
||||
db.Where("name = ?", "Alice").First(&user)
|
||||
|
||||
//order1 := Order{Product: "Laptop"}
|
||||
//order2 := Order{Product: "Mouse"}
|
||||
//order3 := Order{Product: "Keyboard"}
|
||||
|
||||
// 1. Append - 添加关联
|
||||
//db.Model(&user).Association("Orders").Append(&order1, &order2)
|
||||
//fmt.Println("Orders appended")
|
||||
|
||||
// 2. Count - 统计关联数量
|
||||
//count := db.Model(&user).Association("Orders").Count()
|
||||
//fmt.Printf("Order count: %d\n", count)
|
||||
|
||||
// 4. Replace - 替换所有关联
|
||||
//db.Model(&user).Association("Orders").Replace(&order3)
|
||||
|
||||
//查询订单 Keyboard
|
||||
var order3 Order
|
||||
db.Where("product = ?", "Keyboard").First(&order3)
|
||||
|
||||
// 5. Delete - 删除关联(不删除记录本身)
|
||||
//db.Model(&user).Association("Orders").Delete(&order3)
|
||||
//fmt.Println("Association deleted")
|
||||
|
||||
//fmt.Println("Orders replaced with Keyboard")
|
||||
|
||||
// 6. Clear - 清空所有关联
|
||||
//db.Model(&user).Association("Orders").Append(&order3)
|
||||
db.Model(&user).Association("Orders").Clear()
|
||||
fmt.Println("All associations cleared")
|
||||
|
||||
// 3. Find - 查找关联
|
||||
var orders []Order
|
||||
db.Model(&user).Association("Orders").Find(&orders)
|
||||
fmt.Println("Orders found:")
|
||||
for _, o := range orders {
|
||||
fmt.Printf(" - %s\n", o.Product)
|
||||
}
|
||||
}
|
||||
51
Web开发/03go-gorm-demo/crud_create.go
Normal file
51
Web开发/03go-gorm-demo/crud_create.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
// CreatedAt time.Time
|
||||
// }
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
// 1. 单条插入
|
||||
user := User{
|
||||
Name: "Alice",
|
||||
Email: "alice@example.com",
|
||||
Age: 30,
|
||||
}
|
||||
result := db.Create(&user)
|
||||
|
||||
if result.Error != nil {
|
||||
panic(result.Error)
|
||||
}
|
||||
|
||||
fmt.Printf("New user ID: %d\n", user.ID)
|
||||
fmt.Printf("Rows affected: %d\n", result.RowsAffected)
|
||||
|
||||
// 2. 批量插入
|
||||
users := []User{
|
||||
{Name: "Bob", Email: "bob@example.com", Age: 25},
|
||||
{Name: "Charlie", Email: "charlie@example.com", Age: 35},
|
||||
{Name: "David", Email: "david@example.com", Age: 28},
|
||||
}
|
||||
|
||||
db.Create(users)
|
||||
fmt.Println("Batch insert completed!")
|
||||
|
||||
// 3. 指定字段插入
|
||||
user2 := User{Name: "Eve", Email: "eve@example.com", Age: 22}
|
||||
db.Select("name", "email").Create(&user2) // 仅插入 name 和 email
|
||||
|
||||
fmt.Println("All users created successfully!")
|
||||
}
|
||||
56
Web开发/03go-gorm-demo/crud_delete.go
Normal file
56
Web开发/03go-gorm-demo/crud_delete.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
// DeletedAt gorm.DeletedAt `gorm:"index"` // 软删除字段
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
//// 插入测试数据
|
||||
//users := []User{
|
||||
// {Name: "Alice", Email: "alice@example.com", Age: 30},
|
||||
// {Name: "Bob", Email: "bob@example.com", Age: 25},
|
||||
// {Name: "Charlie", Email: "charlie@example.com", Age: 35},
|
||||
//}
|
||||
//db.Create(users)
|
||||
|
||||
// 1. 软删除(标记 deleted_at)
|
||||
db.Delete(&User{}, 11) // 删除 ID=1 的用户
|
||||
fmt.Println("Soft deleted user ID=1")
|
||||
|
||||
// 2. 查询时默认不包括已删除的
|
||||
var activeUsers []User
|
||||
db.Find(&activeUsers)
|
||||
fmt.Printf("Active users: %d\n", len(activeUsers))
|
||||
|
||||
// 3. 查询所有记录(包括已删除的)
|
||||
var allUsers []User
|
||||
db.Unscoped().Find(&allUsers)
|
||||
fmt.Printf("All users (including deleted): %d\n", len(allUsers))
|
||||
|
||||
// 4. 永久删除(硬删除)
|
||||
db.Unscoped().Delete(&User{}, 12)
|
||||
fmt.Println("Permanently deleted user ID=2")
|
||||
|
||||
// 5. 批量删除
|
||||
db.Where("age < ?", 30).Delete(&User{})
|
||||
fmt.Println("Batch delete completed")
|
||||
|
||||
// 最终统计
|
||||
var finalCount int64
|
||||
db.Model(&User{}).Count(&finalCount)
|
||||
fmt.Printf("Final active users: %d\n", finalCount)
|
||||
}
|
||||
72
Web开发/03go-gorm-demo/crud_read.go
Normal file
72
Web开发/03go-gorm-demo/crud_read.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
// CreatedAt time.Time
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
|
||||
// 先插入测试数据
|
||||
db.AutoMigrate(&User{})
|
||||
db.Create(&User{Name: "Alice", Email: "alice@example.com", Age: 30})
|
||||
db.Create(&User{Name: "Bob", Email: "bob@example.com", Age: 25})
|
||||
db.Create(&User{Name: "Charlie", Email: "charlie@example.com", Age: 35})
|
||||
|
||||
// 1. 根据 ID 查询
|
||||
var user User
|
||||
db.First(&user, 1) // 查询 ID=1 的用户
|
||||
fmt.Printf("User ID=1: %s (%s)\n", user.Name, user.Email)
|
||||
|
||||
// 2. 按条件查询单条
|
||||
var user2 User
|
||||
db.Where("email = ?", "bob@example.com").First(&user2)
|
||||
fmt.Printf("User by email: %s (age=%d)\n", user2.Name, user2.Age)
|
||||
|
||||
// 3. 查询所有
|
||||
var users []User
|
||||
db.Find(&users)
|
||||
fmt.Printf("Total users: %d\n", len(users))
|
||||
|
||||
// 4. 按条件查询多条
|
||||
var adults []User
|
||||
db.Where("age >= ?", 30).Find(&adults)
|
||||
fmt.Printf("Users age >= 30: %d\n", len(adults))
|
||||
|
||||
// 5. 使用 IN 查询
|
||||
var selectedUsers []User
|
||||
db.Where("id IN ?", []int{1, 2}).Find(&selectedUsers)
|
||||
fmt.Printf("Selected users: %d\n", len(selectedUsers))
|
||||
|
||||
// 6. 排序查询
|
||||
var sortedUsers []User
|
||||
db.Order("age DESC").Find(&sortedUsers)
|
||||
fmt.Println("Users sorted by age (DESC):")
|
||||
for _, u := range sortedUsers {
|
||||
fmt.Printf(" - %s (age=%d)\n", u.Name, u.Age)
|
||||
}
|
||||
|
||||
// 7. 分页查询
|
||||
var pageUsers []User
|
||||
db.Offset(0).Limit(2).Find(&pageUsers)
|
||||
fmt.Printf("Page 1 (limit 2): %d users\n", len(pageUsers))
|
||||
|
||||
// 8. 组合查询
|
||||
var combinedUsers []User
|
||||
db.Where("age > ?", 25).
|
||||
Order("age DESC").
|
||||
Limit(2).
|
||||
Find(&combinedUsers)
|
||||
fmt.Printf("Combined query: %d users\n", len(combinedUsers))
|
||||
}
|
||||
56
Web开发/03go-gorm-demo/crud_update.go
Normal file
56
Web开发/03go-gorm-demo/crud_update.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
// UpdatedAt time.Time
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
// 插入测试数据
|
||||
user := User{Name: "Alice", Email: "alice@example.com", Age: 30}
|
||||
db.Create(&user)
|
||||
|
||||
// 1. 更新单个字段
|
||||
db.Model(&User{}).Where("id = ?", user.ID).Update("name", "Alice Updated")
|
||||
fmt.Println("Updated single field")
|
||||
|
||||
// 2. 更新多个字段(使用 map)
|
||||
db.Model(&User{}).Where("id = ?", user.ID).Updates(map[string]interface{}{
|
||||
"name": "Alice Smith",
|
||||
"age": 31,
|
||||
})
|
||||
fmt.Println("Updated multiple fields (map)")
|
||||
|
||||
// 3. 更新多个字段(使用 struct,仅更新非零值)
|
||||
db.Model(&User{}).Where("id = ?", user.ID).Updates(User{
|
||||
Name: "Alice Johnson",
|
||||
Age: 32,
|
||||
})
|
||||
fmt.Println("Updated multiple fields (struct)")
|
||||
|
||||
// 4. 强制更新零值字段
|
||||
db.Model(&User{}).Where("id = ?", user.ID).Update("age", 0)
|
||||
fmt.Println("Updated age to zero")
|
||||
|
||||
// 5. 批量更新
|
||||
db.Model(&User{}).Where("age > ?", 25).Update("age", gorm.Expr("age + ?", 1))
|
||||
fmt.Println("Batch update completed")
|
||||
|
||||
// 查询最终结果
|
||||
var finalUser User
|
||||
db.First(&finalUser, user.ID)
|
||||
fmt.Printf("Final user: %s (age=%d)\n", finalUser.Name, finalUser.Age)
|
||||
}
|
||||
29
Web开发/03go-gorm-demo/db_connect.go
Normal file
29
Web开发/03go-gorm-demo/db_connect.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 连接 SQLite(文件数据库)
|
||||
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
}
|
||||
|
||||
fmt.Println("Database connected successfully!")
|
||||
|
||||
// 获取底层的 *sql.DB
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 设置连接池
|
||||
sqlDB.SetMaxIdleConns(10)
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
|
||||
fmt.Println("Connection pool configured")
|
||||
}
|
||||
11
Web开发/03go-gorm-demo/go.mod
Normal file
11
Web开发/03go-gorm-demo/go.mod
Normal file
@@ -0,0 +1,11 @@
|
||||
module go-gorm-demo
|
||||
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||
gorm.io/driver/sqlite v1.5.4 // indirect
|
||||
gorm.io/gorm v1.25.5 // indirect
|
||||
)
|
||||
10
Web开发/03go-gorm-demo/go.sum
Normal file
10
Web开发/03go-gorm-demo/go.sum
Normal file
@@ -0,0 +1,10 @@
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
|
||||
gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
|
||||
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
||||
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
28
Web开发/03go-gorm-demo/model_basic.go
Normal file
28
Web开发/03go-gorm-demo/model_basic.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// // User 模型
|
||||
//
|
||||
// type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100;not null"`
|
||||
// Email string `gorm:"size:100;unique;not null"`
|
||||
// Age int `gorm:"default:0"`
|
||||
// Active bool `gorm:"default:true"`
|
||||
// CreatedAt time.Time
|
||||
// UpdatedAt time.Time
|
||||
// }
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
|
||||
// 自动迁移(创建表)
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
fmt.Println("Table created successfully!")
|
||||
}
|
||||
63
Web开发/03go-gorm-demo/preload_strategies.go
Normal file
63
Web开发/03go-gorm-demo/preload_strategies.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
Name string `gorm:"size:100"`
|
||||
Profile Profile
|
||||
Orders []Order
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
UserID uint
|
||||
Bio string `gorm:"size:200"`
|
||||
}
|
||||
|
||||
type Order struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
UserID uint
|
||||
Product string `gorm:"size:100"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{}, &Profile{}, &Order{})
|
||||
|
||||
// 创建测试数据
|
||||
//user := User{
|
||||
// Name: "Alice",
|
||||
// Profile: Profile{Bio: "Software Engineer"},
|
||||
// Orders: []Order{
|
||||
// {Product: "Laptop"},
|
||||
// {Product: "Mouse"},
|
||||
// },
|
||||
//}
|
||||
//db.Create(&user)
|
||||
|
||||
// 1. 预加载单个关联
|
||||
//var user1 User
|
||||
//db.Preload("Profile").First(&user1, 1)
|
||||
//fmt.Printf("User: %s, Bio: %s\n", user1.Name, user1.Profile.Bio)
|
||||
|
||||
//// 2. 预加载多个关联
|
||||
//var user2 User
|
||||
//db.Preload("Profile").Preload("Orders").First(&user2, 1)
|
||||
//fmt.Printf("User: %s, Orders: %d\n", user2.Name, len(user2.Orders))
|
||||
|
||||
// 3. 预加载所有关联
|
||||
//var user3 User
|
||||
//db.Preload("Profile").Preload("Orders").First(&user3, 1)
|
||||
//fmt.Printf("Fully loaded user: %s\n", user3.Name)
|
||||
|
||||
//// 4. 条件预加载
|
||||
var user4 User
|
||||
db.Preload("Orders", "product = ?", "Laptop").First(&user4, 1)
|
||||
fmt.Printf("Filtered orders: %d\n", len(user4.Orders))
|
||||
}
|
||||
76
Web开发/03go-gorm-demo/query_advanced.go
Normal file
76
Web开发/03go-gorm-demo/query_advanced.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
// Active bool `gorm:"default:true"`
|
||||
// CreatedAt time.Time
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
// 插入测试数据
|
||||
users := []User{
|
||||
{Name: "Alice", Email: "alice@example.com", Age: 30, Active: true},
|
||||
{Name: "Bob", Email: "bob@example.com", Age: 25, Active: false},
|
||||
{Name: "Charlie", Email: "charlie@example.com", Age: 35, Active: true},
|
||||
{Name: "David", Email: "david@example.com", Age: 28, Active: true},
|
||||
}
|
||||
db.Create(users)
|
||||
|
||||
// 1. 多条件查询
|
||||
var result1 []User
|
||||
db.Where("age > ? AND active = ?", 25, true).Find(&result1)
|
||||
fmt.Printf("Age > 25 AND active: %d users\n", len(result1))
|
||||
|
||||
// 2. OR 查询
|
||||
var result2 []User
|
||||
db.Where("age < ? OR active = ?", 30, false).Find(&result2)
|
||||
fmt.Printf("Age < 30 OR inactive: %d users\n", len(result2))
|
||||
|
||||
// 3. 模糊查询
|
||||
var result3 []User
|
||||
db.Where("name LIKE ?", "%li%").Find(&result3)
|
||||
fmt.Printf("Name contains 'li': %d users\n", len(result3))
|
||||
|
||||
// 4. 仅查询指定字段
|
||||
var result4 []User
|
||||
db.Select("name", "email").Find(&result4)
|
||||
fmt.Printf("Selected fields: %d users\n", len(result4))
|
||||
for _, u := range result4 {
|
||||
fmt.Printf(" - %s (%s)\n", u.Name, u.Email)
|
||||
}
|
||||
|
||||
// 5. 统计查询
|
||||
var count int64
|
||||
db.Model(&User{}).Where("active = ?", true).Count(&count)
|
||||
fmt.Printf("Active users count: %d\n", count)
|
||||
|
||||
// 6. 聚合查询
|
||||
var avgAge float64
|
||||
db.Model(&User{}).Select("AVG(age)").Row().Scan(&avgAge)
|
||||
fmt.Printf("Average age: %.2f\n", avgAge)
|
||||
|
||||
// 7. 分组查询
|
||||
type Result struct {
|
||||
Active bool
|
||||
Count int64
|
||||
}
|
||||
var groupResult []Result
|
||||
db.Model(&User{}).Select("active, count(*) as count").Group("active").Scan(&groupResult)
|
||||
fmt.Println("Group by active:")
|
||||
for _, r := range groupResult {
|
||||
fmt.Printf(" Active=%v: %d users\n", r.Active, r.Count)
|
||||
}
|
||||
}
|
||||
47
Web开发/03go-gorm-demo/raw_sql.go
Normal file
47
Web开发/03go-gorm-demo/raw_sql.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
// Active bool `gorm:"default:true"`
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
// 插入测试数据
|
||||
db.Create(&User{Name: "Alice", Email: "alice@example.com", Age: 30})
|
||||
db.Create(&User{Name: "Bob", Email: "bob@example.com", Age: 25})
|
||||
|
||||
// 1. 原生查询
|
||||
var users []User
|
||||
db.Raw("SELECT * FROM users WHERE age > ?", 20).Scan(&users)
|
||||
fmt.Printf("Raw query result: %d users\n", len(users))
|
||||
|
||||
// 2. 原生更新
|
||||
db.Exec("UPDATE users SET age = age + 1 WHERE name = ?", "Alice")
|
||||
fmt.Println("Raw update executed")
|
||||
|
||||
// 3. 原生统计
|
||||
var count int64
|
||||
db.Raw("SELECT COUNT(*) FROM users").Scan(&count)
|
||||
fmt.Printf("Total users: %d\n", count)
|
||||
|
||||
// 4. 查询单行
|
||||
var result struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
db.Raw("SELECT name, age FROM users WHERE id = ?", 1).Scan(&result)
|
||||
fmt.Printf("User: %s (age=%d)\n", result.Name, result.Age)
|
||||
}
|
||||
61
Web开发/03go-gorm-demo/relation_has_many.go
Normal file
61
Web开发/03go-gorm-demo/relation_has_many.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 用户拥有多个订单
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Orders []Order // 一对多关联
|
||||
//}
|
||||
//
|
||||
//type Order struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// UserID uint // 外键
|
||||
// Product string `gorm:"size:100"`
|
||||
// Amount int
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{}, &Order{})
|
||||
|
||||
// 1. 创建用户和订单
|
||||
user := User{
|
||||
Name: "Alice",
|
||||
Orders: []Order{
|
||||
{Product: "Laptop", Amount: 1},
|
||||
{Product: "Mouse", Amount: 2},
|
||||
{Product: "Keyboard", Amount: 1},
|
||||
},
|
||||
}
|
||||
db.Create(&user)
|
||||
fmt.Println("User and orders created")
|
||||
|
||||
// 2. 预加载查询
|
||||
var result User
|
||||
db.Preload("Orders").First(&result, user.ID)
|
||||
fmt.Printf("User: %s, Orders: %d\n", result.Name, len(result.Orders))
|
||||
for _, order := range result.Orders {
|
||||
fmt.Printf(" - %s (x%d)\n", order.Product, order.Amount)
|
||||
}
|
||||
|
||||
// 3. 添加新订单
|
||||
newOrder := Order{UserID: user.ID, Product: "Monitor", Amount: 1}
|
||||
db.Create(&newOrder)
|
||||
fmt.Println("New order added")
|
||||
|
||||
// 4. 查询用户的所有订单
|
||||
var orders []Order
|
||||
db.Where("user_id = ?", user.ID).Find(&orders)
|
||||
fmt.Printf("Total orders: %d\n", len(orders))
|
||||
|
||||
// 5. 删除某个订单
|
||||
db.Delete(&Order{}, orders[0].ID)
|
||||
fmt.Println("First order deleted")
|
||||
}
|
||||
51
Web开发/03go-gorm-demo/relation_has_one.go
Normal file
51
Web开发/03go-gorm-demo/relation_has_one.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 用户拥有一个账户
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Account Account // 一对一关联
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
//}
|
||||
//
|
||||
//type Account struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// UserID uint // 外键
|
||||
// Balance int
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{}, &Account{})
|
||||
|
||||
// 1. 创建用户和账户
|
||||
user := User{
|
||||
Name: "Alice",
|
||||
Account: Account{Balance: 1000},
|
||||
}
|
||||
db.Create(&user)
|
||||
fmt.Println("User and account created")
|
||||
|
||||
// 2. 预加载查询
|
||||
var result User
|
||||
db.Preload("Account").First(&result, user.ID)
|
||||
fmt.Printf("User: %s, Balance: %d\n", result.Name, result.Account.Balance)
|
||||
|
||||
// 3. 更新关联数据
|
||||
db.Model(&result.Account).Update("balance", 2000)
|
||||
fmt.Println("Account balance updated")
|
||||
|
||||
// 4. 删除关联(不会自动删除 Account)
|
||||
db.Delete(&result)
|
||||
|
||||
var accountCount int64
|
||||
db.Model(&Account{}).Count(&accountCount)
|
||||
fmt.Printf("Account still exists: %d\n", accountCount)
|
||||
}
|
||||
96
Web开发/03go-gorm-demo/relation_many_to_many.go
Normal file
96
Web开发/03go-gorm-demo/relation_many_to_many.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 学生和课程:多对多关系
|
||||
type Student struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
Name string `gorm:"size:100"`
|
||||
Courses []Course `gorm:"many2many:student_courses;"` // 多对多
|
||||
}
|
||||
|
||||
type Course struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
Name string `gorm:"size:100"`
|
||||
Students []Student `gorm:"many2many:student_courses;"` // 多对多
|
||||
}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
//db.AutoMigrate(&Student{}, &Course{})
|
||||
|
||||
// 1. 创建课程
|
||||
//math := Course{Name: "Math"}
|
||||
//physics := Course{Name: "Physics"}
|
||||
//chemistry := Course{Name: "Chemistry"}
|
||||
//db.Create(&math)
|
||||
//db.Create(&physics)
|
||||
//db.Create(&chemistry)
|
||||
|
||||
// 2. 创建学生并关联课程
|
||||
//alice := Student{
|
||||
// Name: "Alice",
|
||||
// Courses: []Course{math, physics},
|
||||
//}
|
||||
//bob := Student{
|
||||
// Name: "Bob",
|
||||
// Courses: []Course{physics, chemistry},
|
||||
//}
|
||||
//db.Create(&alice)
|
||||
//db.Create(&bob)
|
||||
//fmt.Println("Students and courses created")
|
||||
|
||||
//查询数据库的alice的学生
|
||||
var alice Student
|
||||
db.Where("name = ?", "Alice").First(&alice)
|
||||
|
||||
//查询数据库的Bob学生
|
||||
var bob Student
|
||||
db.Where("name = ?", "Bob").First(&bob)
|
||||
|
||||
//查询课程
|
||||
var math Course
|
||||
db.Where("name = ?", "Math").First(&math)
|
||||
|
||||
//// 5. 添加关联
|
||||
//db.Model(&alice).Association("Courses").Append(&chemistry)
|
||||
//fmt.Println("Alice enrolled in Chemistry")
|
||||
|
||||
//// 7. 替换所有关联
|
||||
//db.Model(&alice).Association("Courses").Replace(&math)
|
||||
//fmt.Println("Alice now only takes Math")
|
||||
|
||||
// 8. 清空关联
|
||||
db.Model(&bob).Association("Courses").Clear()
|
||||
fmt.Println("Bob dropped all courses")
|
||||
|
||||
// 3. 查询学生的课程
|
||||
var student1 Student
|
||||
db.Preload("Courses").First(&student1, 1)
|
||||
fmt.Printf("%s's courses:\n", student1.Name)
|
||||
for _, course := range student1.Courses {
|
||||
fmt.Printf(" - %s\n", course.Name)
|
||||
}
|
||||
|
||||
// 4. 查询课程的学生
|
||||
var course1 Course
|
||||
db.Preload("Students").First(&course1, 1)
|
||||
fmt.Printf("%s course students:\n", course1.Name)
|
||||
for _, student := range course1.Students {
|
||||
fmt.Printf(" - %s\n", student.Name)
|
||||
}
|
||||
|
||||
//查询bob的课程
|
||||
var student2 Student
|
||||
db.Preload("Courses").First(&student2, 2)
|
||||
fmt.Printf("%s's courses:\n", student2.Name)
|
||||
for _, course := range student2.Courses {
|
||||
fmt.Printf(" - %s\n", course.Name)
|
||||
}
|
||||
|
||||
}
|
||||
BIN
Web开发/03go-gorm-demo/test.db
Normal file
BIN
Web开发/03go-gorm-demo/test.db
Normal file
Binary file not shown.
70
Web开发/03go-gorm-demo/transaction_basic.go
Normal file
70
Web开发/03go-gorm-demo/transaction_basic.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// Age int
|
||||
//}
|
||||
//
|
||||
//type Account struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// UserID uint
|
||||
// Balance int
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{}, &Account{})
|
||||
|
||||
// 1. 手动事务
|
||||
tx := db.Begin()
|
||||
|
||||
// 创建用户
|
||||
user := User{Name: "Alice", Email: "alice@example.com"}
|
||||
if err := tx.Create(&user).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 创建账户
|
||||
account := Account{UserID: user.ID, Balance: 1000}
|
||||
if err := tx.Create(&account).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
fmt.Println("Transaction committed successfully!")
|
||||
|
||||
// 2. 自动事务(推荐)
|
||||
err := db.Transaction(func(tx *gorm.DB) error {
|
||||
// 在事务中执行操作
|
||||
user2 := User{Name: "Bob", Email: "bob@example.com"}
|
||||
if err := tx.Create(&user2).Error; err != nil {
|
||||
return err // 自动回滚
|
||||
}
|
||||
|
||||
account2 := Account{UserID: user2.ID, Balance: 2000}
|
||||
if err := tx.Create(&account2).Error; err != nil {
|
||||
return err // 自动回滚
|
||||
}
|
||||
|
||||
// 返回 nil 自动提交
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Transaction failed:", err)
|
||||
} else {
|
||||
fmt.Println("Auto transaction committed successfully!")
|
||||
}
|
||||
}
|
||||
47
Web开发/03go-gorm-demo/transaction_rollback.go
Normal file
47
Web开发/03go-gorm-demo/transaction_rollback.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
// }
|
||||
//type Account struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// UserID uint
|
||||
// Balance int
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{}, &Account{})
|
||||
|
||||
// 故意触发错误,测试回滚
|
||||
err := db.Transaction(func(tx *gorm.DB) error {
|
||||
user := User{Name: "Charlie", Email: "charlie@example.com"}
|
||||
if err := tx.Create(&user).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("User created, ID:", user.ID)
|
||||
|
||||
// 故意返回错误,触发回滚
|
||||
return errors.New("something went wrong")
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Transaction rolled back:", err)
|
||||
}
|
||||
|
||||
// 检查用户是否存在
|
||||
var count int64
|
||||
db.Model(&User{}).Where("name = ?", "Charlie").Count(&count)
|
||||
fmt.Printf("User 'Charlie' count: %d (should be 0)\n", count)
|
||||
}
|
||||
37
Web开发/03go-gorm-demo/transaction_savepoint.go
Normal file
37
Web开发/03go-gorm-demo/transaction_savepoint.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//type User struct {
|
||||
// ID uint `gorm:"primaryKey"`
|
||||
// Name string `gorm:"size:100"`
|
||||
// Email string `gorm:"size:100;unique"`
|
||||
//}
|
||||
|
||||
func main() {
|
||||
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
db.Transaction(func(tx *gorm.DB) error {
|
||||
tx.Create(&User{Name: "Alice", Email: "alice@example.com"})
|
||||
|
||||
// 创建 SavePoint
|
||||
tx.SavePoint("sp1")
|
||||
tx.Create(&User{Name: "Bob", Email: "bob@example.com"})
|
||||
|
||||
// 回滚到 SavePoint
|
||||
tx.RollbackTo("sp1")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
// 检查结果
|
||||
var count int64
|
||||
db.Model(&User{}).Count(&count)
|
||||
fmt.Printf("Total users: %d (should be 1, only Alice)\n", count)
|
||||
}
|
||||
Reference in New Issue
Block a user