785 lines
21 KiB
Go
785 lines
21 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"database/sql"
|
|||
|
"fmt"
|
|||
|
"log"
|
|||
|
|
|||
|
// 实际使用时请替换为正确的导入路径
|
|||
|
// "code.hoteas.com/golang/hotime/cache"
|
|||
|
// "code.hoteas.com/golang/hotime/common"
|
|||
|
// "code.hoteas.com/golang/hotime/db"
|
|||
|
"code.hoteas.com/golang/hotime/cache"
|
|||
|
"code.hoteas.com/golang/hotime/common"
|
|||
|
"code.hoteas.com/golang/hotime/db"
|
|||
|
_ "github.com/go-sql-driver/mysql"
|
|||
|
"github.com/sirupsen/logrus"
|
|||
|
)
|
|||
|
|
|||
|
// HoTimeDB使用示例代码集合 - 修正版
|
|||
|
// 本文件包含了各种常见场景的完整示例代码,所有条件查询语法已修正
|
|||
|
|
|||
|
// 示例1: 基本初始化和配置
|
|||
|
func Example1_BasicSetup() {
|
|||
|
// 创建数据库实例
|
|||
|
database := &db.HoTimeDB{
|
|||
|
Prefix: "app_", // 设置表前缀
|
|||
|
Mode: 2, // 开发模式,输出SQL日志
|
|||
|
Type: "mysql", // 数据库类型
|
|||
|
}
|
|||
|
|
|||
|
// 设置日志
|
|||
|
logger := logrus.New()
|
|||
|
database.Log = logger
|
|||
|
|
|||
|
// 设置连接函数
|
|||
|
database.SetConnect(func(err ...*common.Error) (master, slave *sql.DB) {
|
|||
|
// 主数据库连接
|
|||
|
master, dbErr := sql.Open("mysql", "root:password@tcp(localhost:3306)/testdb?charset=utf8&parseTime=true")
|
|||
|
if dbErr != nil {
|
|||
|
log.Fatal("数据库连接失败:", dbErr)
|
|||
|
}
|
|||
|
|
|||
|
// 从数据库连接(可选,用于读写分离)
|
|||
|
slave = master // 这里使用同一个连接,实际项目中可以连接到从库
|
|||
|
|
|||
|
return master, slave
|
|||
|
})
|
|||
|
|
|||
|
fmt.Println("数据库初始化完成")
|
|||
|
}
|
|||
|
|
|||
|
// 示例2: 基本CRUD操作(修正版)
|
|||
|
func Example2_BasicCRUD_Fixed(db *db.HoTimeDB) {
|
|||
|
// 创建用户
|
|||
|
fmt.Println("=== 创建用户 ===")
|
|||
|
userId := db.Insert("user", common.Map{
|
|||
|
"name": "张三",
|
|||
|
"email": "zhangsan@example.com",
|
|||
|
"age": 25,
|
|||
|
"status": 1,
|
|||
|
"balance": 1000.50,
|
|||
|
"created_time[#]": "NOW()",
|
|||
|
})
|
|||
|
fmt.Printf("新用户ID: %d\n", userId)
|
|||
|
|
|||
|
// 查询用户(单条件,可以不用AND)
|
|||
|
fmt.Println("\n=== 查询用户 ===")
|
|||
|
user := db.Get("user", "*", common.Map{
|
|||
|
"id": userId,
|
|||
|
})
|
|||
|
if user != nil {
|
|||
|
fmt.Printf("用户信息: %+v\n", user)
|
|||
|
}
|
|||
|
|
|||
|
// 更新用户(多条件必须用AND包装)
|
|||
|
fmt.Println("\n=== 更新用户 ===")
|
|||
|
affected := db.Update("user", common.Map{
|
|||
|
"name": "李四",
|
|||
|
"age": 26,
|
|||
|
"updated_time[#]": "NOW()",
|
|||
|
}, common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"id": userId,
|
|||
|
"status": 1, // 确保只更新正常状态的用户
|
|||
|
},
|
|||
|
})
|
|||
|
fmt.Printf("更新记录数: %d\n", affected)
|
|||
|
|
|||
|
// 软删除用户
|
|||
|
fmt.Println("\n=== 软删除用户 ===")
|
|||
|
affected = db.Update("user", common.Map{
|
|||
|
"deleted_at[#]": "NOW()",
|
|||
|
"status": 0,
|
|||
|
}, common.Map{
|
|||
|
"id": userId, // 单条件,不需要AND
|
|||
|
})
|
|||
|
fmt.Printf("软删除记录数: %d\n", affected)
|
|||
|
}
|
|||
|
|
|||
|
// 示例3: 条件查询语法(修正版)
|
|||
|
func Example3_ConditionQuery_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 条件查询语法示例 ===")
|
|||
|
|
|||
|
// ✅ 正确:单个条件
|
|||
|
users1 := db.Select("user", "*", common.Map{
|
|||
|
"status": 1,
|
|||
|
})
|
|||
|
fmt.Printf("活跃用户: %d个\n", len(users1))
|
|||
|
|
|||
|
// ✅ 正确:多个条件用AND包装
|
|||
|
users2 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"status": 1,
|
|||
|
"age[>]": 18,
|
|||
|
"age[<=]": 60,
|
|||
|
},
|
|||
|
})
|
|||
|
fmt.Printf("活跃的成年用户: %d个\n", len(users2))
|
|||
|
|
|||
|
// ✅ 正确:OR条件
|
|||
|
users3 := db.Select("user", "*", common.Map{
|
|||
|
"OR": common.Map{
|
|||
|
"level": "vip",
|
|||
|
"balance[>]": 5000,
|
|||
|
},
|
|||
|
})
|
|||
|
fmt.Printf("VIP或高余额用户: %d个\n", len(users3))
|
|||
|
|
|||
|
// ✅ 正确:条件 + 特殊参数
|
|||
|
users4 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"status": 1,
|
|||
|
"age[>=]": 18,
|
|||
|
},
|
|||
|
"ORDER": "created_time DESC",
|
|||
|
"LIMIT": 10,
|
|||
|
})
|
|||
|
fmt.Printf("最近的活跃成年用户: %d个\n", len(users4))
|
|||
|
|
|||
|
// ✅ 正确:复杂嵌套条件
|
|||
|
users5 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"status": 1,
|
|||
|
"OR": common.Map{
|
|||
|
"age[<]": 30,
|
|||
|
"level": "vip",
|
|||
|
},
|
|||
|
},
|
|||
|
"ORDER": []string{"level DESC", "created_time DESC"},
|
|||
|
"LIMIT": []int{0, 20},
|
|||
|
})
|
|||
|
fmt.Printf("年轻或VIP的活跃用户: %d个\n", len(users5))
|
|||
|
|
|||
|
// ✅ 正确:模糊查询
|
|||
|
users6 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"name[~]": "张", // 姓名包含"张"
|
|||
|
"email[~!]": "gmail", // 邮箱以gmail开头
|
|||
|
"status": 1,
|
|||
|
},
|
|||
|
})
|
|||
|
fmt.Printf("姓张的gmail活跃用户: %d个\n", len(users6))
|
|||
|
|
|||
|
// ✅ 正确:范围查询
|
|||
|
users7 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"age[<>]": []int{18, 35}, // 年龄在18-35之间
|
|||
|
"balance[><]": []float64{0, 100}, // 余额不在0-100之间
|
|||
|
"status": 1,
|
|||
|
},
|
|||
|
})
|
|||
|
fmt.Printf("18-35岁且余额>100的活跃用户: %d个\n", len(users7))
|
|||
|
|
|||
|
// ✅ 正确:IN查询
|
|||
|
users8 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"id": []int{1, 2, 3, 4, 5}, // ID在指定范围内
|
|||
|
"status[!]": []int{0, -1}, // 状态不为0或-1
|
|||
|
},
|
|||
|
})
|
|||
|
fmt.Printf("指定ID的活跃用户: %d个\n", len(users8))
|
|||
|
}
|
|||
|
|
|||
|
// 示例4: 链式查询操作(正确版)
|
|||
|
func Example4_ChainQuery_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 链式查询示例 ===")
|
|||
|
|
|||
|
// 链式查询(链式语法允许单独的Where,然后用And添加更多条件)
|
|||
|
users := db.Table("user").
|
|||
|
Where("status", 1). // 链式中可以单独Where
|
|||
|
And("age[>=]", 18). // 然后用And添加条件
|
|||
|
And("age[<=]", 60). // 再添加条件
|
|||
|
Or(common.Map{ // 或者用Or添加OR条件组
|
|||
|
"level": "vip",
|
|||
|
"balance[>]": 5000,
|
|||
|
}).
|
|||
|
Order("created_time DESC", "id ASC"). // 排序
|
|||
|
Limit(0, 10). // 限制结果
|
|||
|
Select("id,name,email,age,balance,level")
|
|||
|
|
|||
|
fmt.Printf("链式查询到 %d 个用户\n", len(users))
|
|||
|
for i, user := range users {
|
|||
|
fmt.Printf("用户%d: %s (年龄:%v, 余额:%v)\n",
|
|||
|
i+1,
|
|||
|
user.GetString("name"),
|
|||
|
user.Get("age"),
|
|||
|
user.Get("balance"))
|
|||
|
}
|
|||
|
|
|||
|
// 链式统计查询
|
|||
|
count := db.Table("user").
|
|||
|
Where("status", 1).
|
|||
|
And("age[>=]", 18).
|
|||
|
Count()
|
|||
|
fmt.Printf("符合条件的用户总数: %d\n", count)
|
|||
|
}
|
|||
|
|
|||
|
// 示例5: JOIN查询操作(修正版)
|
|||
|
func Example5_JoinQuery_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== JOIN查询示例 ===")
|
|||
|
|
|||
|
// 链式JOIN查询
|
|||
|
orders := db.Table("order").
|
|||
|
LeftJoin("user", "order.user_id = user.id").
|
|||
|
LeftJoin("product", "order.product_id = product.id").
|
|||
|
Where("order.status", "paid"). // 链式中单个条件可以直接Where
|
|||
|
And("order.created_time[>]", "2023-01-01"). // 用And添加更多条件
|
|||
|
Order("order.created_time DESC").
|
|||
|
Select(`
|
|||
|
order.id as order_id,
|
|||
|
order.amount,
|
|||
|
order.status,
|
|||
|
order.created_time,
|
|||
|
user.name as user_name,
|
|||
|
user.email as user_email,
|
|||
|
product.title as product_title,
|
|||
|
product.price as product_price
|
|||
|
`)
|
|||
|
|
|||
|
fmt.Printf("链式JOIN查询到 %d 个订单\n", len(orders))
|
|||
|
for _, order := range orders {
|
|||
|
fmt.Printf("订单ID:%v, 用户:%s, 商品:%s, 金额:%v\n",
|
|||
|
order.Get("order_id"),
|
|||
|
order.GetString("user_name"),
|
|||
|
order.GetString("product_title"),
|
|||
|
order.Get("amount"))
|
|||
|
}
|
|||
|
|
|||
|
// 传统JOIN语法(多个条件必须用AND包装)
|
|||
|
orders2 := db.Select("order",
|
|||
|
common.Slice{
|
|||
|
common.Map{"[>]user": "order.user_id = user.id"},
|
|||
|
common.Map{"[>]product": "order.product_id = product.id"},
|
|||
|
},
|
|||
|
"order.*, user.name as user_name, product.title as product_title",
|
|||
|
common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"order.status": "paid",
|
|||
|
"order.created_time[>]": "2023-01-01",
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
fmt.Printf("传统JOIN语法查询到 %d 个订单\n", len(orders2))
|
|||
|
}
|
|||
|
|
|||
|
// 示例6: 分页查询(修正版)
|
|||
|
func Example6_PaginationQuery_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 分页查询示例 ===")
|
|||
|
|
|||
|
page := 2
|
|||
|
pageSize := 10
|
|||
|
|
|||
|
// 获取总数(单条件)
|
|||
|
total := db.Count("user", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"status": 1,
|
|||
|
"deleted_at": nil,
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
// 分页数据(链式方式)
|
|||
|
users := db.Table("user").
|
|||
|
Where("status", 1).
|
|||
|
And("deleted_at", nil).
|
|||
|
Order("created_time DESC").
|
|||
|
Page(page, pageSize).
|
|||
|
Select("id,name,email,created_time")
|
|||
|
|
|||
|
// 使用传统方式的分页查询
|
|||
|
users2 := db.Page(page, pageSize).PageSelect("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"status": 1,
|
|||
|
"deleted_at": nil,
|
|||
|
},
|
|||
|
"ORDER": "created_time DESC",
|
|||
|
})
|
|||
|
|
|||
|
// 计算分页信息
|
|||
|
totalPages := (total + pageSize - 1) / pageSize
|
|||
|
offset := (page - 1) * pageSize
|
|||
|
|
|||
|
fmt.Printf("总记录数: %d\n", total)
|
|||
|
fmt.Printf("总页数: %d\n", totalPages)
|
|||
|
fmt.Printf("当前页: %d\n", page)
|
|||
|
fmt.Printf("每页大小: %d\n", pageSize)
|
|||
|
fmt.Printf("偏移量: %d\n", offset)
|
|||
|
fmt.Printf("链式查询当前页记录数: %d\n", len(users))
|
|||
|
fmt.Printf("传统查询当前页记录数: %d\n", len(users2))
|
|||
|
|
|||
|
for i, user := range users {
|
|||
|
fmt.Printf(" %d. %s (%s) - %v\n",
|
|||
|
offset+i+1,
|
|||
|
user.GetString("name"),
|
|||
|
user.GetString("email"),
|
|||
|
user.Get("created_time"))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 示例7: 聚合函数查询(修正版)
|
|||
|
func Example7_AggregateQuery_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 聚合函数查询示例 ===")
|
|||
|
|
|||
|
// 基本统计
|
|||
|
userCount := db.Count("user")
|
|||
|
activeUserCount := db.Count("user", common.Map{"status": 1})
|
|||
|
totalBalance := db.Sum("user", "balance", common.Map{"status": 1})
|
|||
|
|
|||
|
fmt.Printf("总用户数: %d\n", userCount)
|
|||
|
fmt.Printf("活跃用户数: %d\n", activeUserCount)
|
|||
|
fmt.Printf("活跃用户总余额: %.2f\n", totalBalance)
|
|||
|
|
|||
|
// 分组统计(正确语法)
|
|||
|
stats := db.Select("user",
|
|||
|
"level, COUNT(*) as user_count, AVG(age) as avg_age, SUM(balance) as total_balance",
|
|||
|
common.Map{
|
|||
|
"status": 1, // 单条件,不需要AND
|
|||
|
"GROUP": "level",
|
|||
|
"ORDER": "user_count DESC",
|
|||
|
})
|
|||
|
|
|||
|
fmt.Println("\n按等级分组统计:")
|
|||
|
for _, stat := range stats {
|
|||
|
fmt.Printf("等级:%v, 用户数:%v, 平均年龄:%v, 总余额:%v\n",
|
|||
|
stat.Get("level"),
|
|||
|
stat.Get("user_count"),
|
|||
|
stat.Get("avg_age"),
|
|||
|
stat.Get("total_balance"))
|
|||
|
}
|
|||
|
|
|||
|
// 关联统计(修正版)
|
|||
|
orderStats := db.Select("order",
|
|||
|
common.Slice{
|
|||
|
common.Map{"[>]user": "order.user_id = user.id"},
|
|||
|
},
|
|||
|
"user.level, COUNT(order.id) as order_count, SUM(order.amount) as total_amount",
|
|||
|
common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"order.status": "paid",
|
|||
|
"order.created_time[>]": "2023-01-01",
|
|||
|
},
|
|||
|
"GROUP": "user.level",
|
|||
|
"ORDER": "total_amount DESC",
|
|||
|
})
|
|||
|
|
|||
|
fmt.Println("\n用户等级订单统计:")
|
|||
|
for _, stat := range orderStats {
|
|||
|
fmt.Printf("等级:%v, 订单数:%v, 总金额:%v\n",
|
|||
|
stat.Get("level"),
|
|||
|
stat.Get("order_count"),
|
|||
|
stat.Get("total_amount"))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 示例8: 事务处理(修正版)
|
|||
|
func Example8_Transaction_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 事务处理示例 ===")
|
|||
|
|
|||
|
// 模拟转账操作
|
|||
|
fromUserId := int64(1)
|
|||
|
toUserId := int64(2)
|
|||
|
amount := 100.0
|
|||
|
|
|||
|
success := db.Action(func(tx db.HoTimeDB) bool {
|
|||
|
// 检查转出账户余额(单条件)
|
|||
|
fromUser := tx.Get("user", "balance", common.Map{"id": fromUserId})
|
|||
|
if fromUser == nil {
|
|||
|
fmt.Println("转出用户不存在")
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
fromBalance := fromUser.GetFloat64("balance")
|
|||
|
if fromBalance < amount {
|
|||
|
fmt.Println("余额不足")
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// 扣减转出账户余额(多条件必须用AND)
|
|||
|
affected1 := tx.Update("user", common.Map{
|
|||
|
"balance[#]": fmt.Sprintf("balance - %.2f", amount),
|
|||
|
"updated_time[#]": "NOW()",
|
|||
|
}, common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"id": fromUserId,
|
|||
|
"balance[>=]": amount, // 再次确保余额足够
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
if affected1 == 0 {
|
|||
|
fmt.Println("扣减余额失败")
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// 增加转入账户余额(单条件)
|
|||
|
affected2 := tx.Update("user", common.Map{
|
|||
|
"balance[#]": fmt.Sprintf("balance + %.2f", amount),
|
|||
|
"updated_time[#]": "NOW()",
|
|||
|
}, common.Map{
|
|||
|
"id": toUserId,
|
|||
|
})
|
|||
|
|
|||
|
if affected2 == 0 {
|
|||
|
fmt.Println("增加余额失败")
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// 记录转账日志
|
|||
|
logId := tx.Insert("transfer_log", common.Map{
|
|||
|
"from_user_id": fromUserId,
|
|||
|
"to_user_id": toUserId,
|
|||
|
"amount": amount,
|
|||
|
"status": "success",
|
|||
|
"created_time[#]": "NOW()",
|
|||
|
})
|
|||
|
|
|||
|
if logId == 0 {
|
|||
|
fmt.Println("记录日志失败")
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
fmt.Printf("转账成功: 用户%d -> 用户%d, 金额:%.2f\n", fromUserId, toUserId, amount)
|
|||
|
return true
|
|||
|
})
|
|||
|
|
|||
|
if success {
|
|||
|
fmt.Println("事务执行成功")
|
|||
|
} else {
|
|||
|
fmt.Println("事务回滚")
|
|||
|
if db.LastErr.GetError() != nil {
|
|||
|
fmt.Println("错误原因:", db.LastErr.GetError())
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 示例9: 缓存机制(修正版)
|
|||
|
func Example9_CacheSystem_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 缓存机制示例 ===")
|
|||
|
|
|||
|
// 设置缓存(实际项目中需要配置缓存参数)
|
|||
|
db.HoTimeCache = &cache.HoTimeCache{}
|
|||
|
|
|||
|
// 第一次查询(会缓存结果)
|
|||
|
fmt.Println("第一次查询(会缓存)...")
|
|||
|
users1 := db.Select("user", "*", common.Map{
|
|||
|
"status": 1, // 单条件
|
|||
|
"LIMIT": 10,
|
|||
|
})
|
|||
|
fmt.Printf("查询到 %d 个用户\n", len(users1))
|
|||
|
|
|||
|
// 第二次相同查询(从缓存获取)
|
|||
|
fmt.Println("第二次相同查询(从缓存获取)...")
|
|||
|
users2 := db.Select("user", "*", common.Map{
|
|||
|
"status": 1, // 单条件
|
|||
|
"LIMIT": 10,
|
|||
|
})
|
|||
|
fmt.Printf("查询到 %d 个用户\n", len(users2))
|
|||
|
|
|||
|
// 更新操作会清除缓存
|
|||
|
fmt.Println("执行更新操作(会清除缓存)...")
|
|||
|
affected := db.Update("user", common.Map{
|
|||
|
"updated_time[#]": "NOW()",
|
|||
|
}, common.Map{
|
|||
|
"id": 1, // 单条件
|
|||
|
})
|
|||
|
fmt.Printf("更新 %d 条记录\n", affected)
|
|||
|
|
|||
|
// 再次查询(重新从数据库获取并缓存)
|
|||
|
fmt.Println("更新后再次查询(重新缓存)...")
|
|||
|
users3 := db.Select("user", "*", common.Map{
|
|||
|
"status": 1, // 单条件
|
|||
|
"LIMIT": 10,
|
|||
|
})
|
|||
|
fmt.Printf("查询到 %d 个用户\n", len(users3))
|
|||
|
}
|
|||
|
|
|||
|
// 示例10: 性能优化技巧(修正版)
|
|||
|
func Example10_PerformanceOptimization_Fixed(db *db.HoTimeDB) {
|
|||
|
fmt.Println("=== 性能优化技巧示例 ===")
|
|||
|
|
|||
|
// IN查询优化(连续数字自动转为BETWEEN)
|
|||
|
fmt.Println("IN查询优化示例...")
|
|||
|
users := db.Select("user", "*", common.Map{
|
|||
|
"id": []int{1, 2, 3, 4, 5, 10, 11, 12, 13, 20}, // 单个IN条件,会被优化
|
|||
|
})
|
|||
|
fmt.Printf("查询到 %d 个用户\n", len(users))
|
|||
|
fmt.Println("执行的SQL:", db.LastQuery)
|
|||
|
|
|||
|
// 批量插入(使用事务)
|
|||
|
fmt.Println("\n批量插入示例...")
|
|||
|
success := db.Action(func(tx db.HoTimeDB) bool {
|
|||
|
for i := 1; i <= 100; i++ {
|
|||
|
id := tx.Insert("user_batch", common.Map{
|
|||
|
"name": fmt.Sprintf("批量用户%d", i),
|
|||
|
"email": fmt.Sprintf("batch%d@example.com", i),
|
|||
|
"status": 1,
|
|||
|
"created_time[#]": "NOW()",
|
|||
|
})
|
|||
|
if id == 0 {
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// 每10个用户输出一次进度
|
|||
|
if i%10 == 0 {
|
|||
|
fmt.Printf("已插入 %d 个用户\n", i)
|
|||
|
}
|
|||
|
}
|
|||
|
return true
|
|||
|
})
|
|||
|
|
|||
|
if success {
|
|||
|
fmt.Println("批量插入完成")
|
|||
|
} else {
|
|||
|
fmt.Println("批量插入失败")
|
|||
|
}
|
|||
|
|
|||
|
// 索引友好的查询(修正版)
|
|||
|
fmt.Println("\n索引友好的查询...")
|
|||
|
recentUsers := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"created_time[>]": "2023-01-01", // 假设created_time有索引
|
|||
|
"status": 1, // 假设status有索引
|
|||
|
},
|
|||
|
"ORDER": "created_time DESC", // 利用索引排序
|
|||
|
"LIMIT": 20,
|
|||
|
})
|
|||
|
fmt.Printf("查询到 %d 个近期用户\n", len(recentUsers))
|
|||
|
}
|
|||
|
|
|||
|
// 完整的应用示例(修正版)
|
|||
|
func CompleteExample_Fixed() {
|
|||
|
fmt.Println("=== HoTimeDB完整应用示例(修正版) ===")
|
|||
|
|
|||
|
// 初始化数据库
|
|||
|
database := &db.HoTimeDB{
|
|||
|
Prefix: "app_",
|
|||
|
Mode: 1, // 测试模式
|
|||
|
Type: "mysql",
|
|||
|
}
|
|||
|
|
|||
|
// 设置连接
|
|||
|
database.SetConnect(func(err ...*common.Error) (master, slave *sql.DB) {
|
|||
|
// 这里使用实际的数据库连接字符串
|
|||
|
dsn := "root:password@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
|
|||
|
master, dbErr := sql.Open("mysql", dsn)
|
|||
|
if dbErr != nil {
|
|||
|
log.Fatal("数据库连接失败:", dbErr)
|
|||
|
}
|
|||
|
return master, master
|
|||
|
})
|
|||
|
|
|||
|
// 用户管理系统示例
|
|||
|
fmt.Println("\n=== 用户管理系统 ===")
|
|||
|
|
|||
|
// 1. 创建用户
|
|||
|
userId := database.Insert("user", common.Map{
|
|||
|
"name": "示例用户",
|
|||
|
"email": "example@test.com",
|
|||
|
"password": "hashed_password",
|
|||
|
"age": 28,
|
|||
|
"status": 1,
|
|||
|
"level": "normal",
|
|||
|
"balance": 500.00,
|
|||
|
"created_time[#]": "NOW()",
|
|||
|
})
|
|||
|
fmt.Printf("创建用户成功,ID: %d\n", userId)
|
|||
|
|
|||
|
// 2. 用户登录更新(多条件用AND)
|
|||
|
database.Update("user", common.Map{
|
|||
|
"last_login[#]": "NOW()",
|
|||
|
"login_count[#]": "login_count + 1",
|
|||
|
}, common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"id": userId,
|
|||
|
"status": 1,
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
// 3. 创建订单
|
|||
|
orderId := database.Insert("order", common.Map{
|
|||
|
"user_id": userId,
|
|||
|
"amount": 299.99,
|
|||
|
"status": "pending",
|
|||
|
"created_time[#]": "NOW()",
|
|||
|
})
|
|||
|
fmt.Printf("创建订单成功,ID: %d\n", orderId)
|
|||
|
|
|||
|
// 4. 订单支付(使用事务,修正版)
|
|||
|
paymentSuccess := database.Action(func(tx db.HoTimeDB) bool {
|
|||
|
// 更新订单状态(单条件)
|
|||
|
affected1 := tx.Update("order", common.Map{
|
|||
|
"status": "paid",
|
|||
|
"paid_time[#]": "NOW()",
|
|||
|
}, common.Map{
|
|||
|
"id": orderId,
|
|||
|
})
|
|||
|
|
|||
|
if affected1 == 0 {
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// 扣减用户余额(多条件用AND)
|
|||
|
affected2 := tx.Update("user", common.Map{
|
|||
|
"balance[#]": "balance - 299.99",
|
|||
|
}, common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"id": userId,
|
|||
|
"balance[>=]": 299.99, // 确保余额足够
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
if affected2 == 0 {
|
|||
|
fmt.Println("余额不足或用户不存在")
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// 记录支付日志
|
|||
|
logId := tx.Insert("payment_log", common.Map{
|
|||
|
"user_id": userId,
|
|||
|
"order_id": orderId,
|
|||
|
"amount": 299.99,
|
|||
|
"type": "order_payment",
|
|||
|
"status": "success",
|
|||
|
"created_time[#]": "NOW()",
|
|||
|
})
|
|||
|
|
|||
|
return logId > 0
|
|||
|
})
|
|||
|
|
|||
|
if paymentSuccess {
|
|||
|
fmt.Println("订单支付成功")
|
|||
|
} else {
|
|||
|
fmt.Println("订单支付失败")
|
|||
|
}
|
|||
|
|
|||
|
// 5. 查询用户订单列表(链式查询)
|
|||
|
userOrders := database.Table("order").
|
|||
|
LeftJoin("user", "order.user_id = user.id").
|
|||
|
Where("order.user_id", userId). // 链式中单个条件可以直接Where
|
|||
|
Order("order.created_time DESC").
|
|||
|
Select(`
|
|||
|
order.id,
|
|||
|
order.amount,
|
|||
|
order.status,
|
|||
|
order.created_time,
|
|||
|
order.paid_time,
|
|||
|
user.name as user_name
|
|||
|
`)
|
|||
|
|
|||
|
fmt.Printf("\n用户订单列表 (%d个订单):\n", len(userOrders))
|
|||
|
for _, order := range userOrders {
|
|||
|
fmt.Printf(" 订单ID:%v, 金额:%v, 状态:%s, 创建时间:%v\n",
|
|||
|
order.Get("id"),
|
|||
|
order.Get("amount"),
|
|||
|
order.GetString("status"),
|
|||
|
order.Get("created_time"))
|
|||
|
}
|
|||
|
|
|||
|
// 6. 生成统计报表(修正版)
|
|||
|
stats := database.Select("order",
|
|||
|
common.Slice{
|
|||
|
common.Map{"[>]user": "order.user_id = user.id"},
|
|||
|
},
|
|||
|
`
|
|||
|
DATE(order.created_time) as date,
|
|||
|
COUNT(order.id) as order_count,
|
|||
|
SUM(order.amount) as total_amount,
|
|||
|
AVG(order.amount) as avg_amount
|
|||
|
`,
|
|||
|
common.Map{
|
|||
|
"AND": common.Map{
|
|||
|
"order.status": "paid",
|
|||
|
"order.created_time[>]": "2023-01-01",
|
|||
|
},
|
|||
|
"GROUP": "DATE(order.created_time)",
|
|||
|
"ORDER": "date DESC",
|
|||
|
"LIMIT": 30,
|
|||
|
})
|
|||
|
|
|||
|
fmt.Printf("\n最近30天订单统计:\n")
|
|||
|
for _, stat := range stats {
|
|||
|
fmt.Printf("日期:%v, 订单数:%v, 总金额:%v, 平均金额:%v\n",
|
|||
|
stat.Get("date"),
|
|||
|
stat.Get("order_count"),
|
|||
|
stat.Get("total_amount"),
|
|||
|
stat.Get("avg_amount"))
|
|||
|
}
|
|||
|
|
|||
|
fmt.Println("\n示例执行完成!")
|
|||
|
}
|
|||
|
|
|||
|
// 语法对比示例
|
|||
|
func SyntaxComparison() {
|
|||
|
fmt.Println("=== HoTimeDB语法对比 ===")
|
|||
|
|
|||
|
// 模拟数据库对象
|
|||
|
var db *db.HoTimeDB
|
|||
|
|
|||
|
fmt.Println("❌ 错误语法示例(不支持):")
|
|||
|
fmt.Println(`
|
|||
|
// 这样写是错误的,多个条件不能直接放在根Map中
|
|||
|
wrongUsers := db.Select("user", "*", common.Map{
|
|||
|
"status": 1, // ❌ 错误
|
|||
|
"age[>]": 18, // ❌ 错误
|
|||
|
"ORDER": "id DESC",
|
|||
|
})
|
|||
|
`)
|
|||
|
|
|||
|
fmt.Println("✅ 正确语法示例:")
|
|||
|
fmt.Println(`
|
|||
|
// 单个条件可以直接写
|
|||
|
correctUsers1 := db.Select("user", "*", common.Map{
|
|||
|
"status": 1, // ✅ 正确,单个条件
|
|||
|
})
|
|||
|
|
|||
|
// 多个条件必须用AND包装
|
|||
|
correctUsers2 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{ // ✅ 正确,多个条件用AND包装
|
|||
|
"status": 1,
|
|||
|
"age[>]": 18,
|
|||
|
},
|
|||
|
"ORDER": "id DESC", // ✅ 正确,特殊参数与条件同级
|
|||
|
})
|
|||
|
|
|||
|
// OR条件
|
|||
|
correctUsers3 := db.Select("user", "*", common.Map{
|
|||
|
"OR": common.Map{ // ✅ 正确,OR条件
|
|||
|
"level": "vip",
|
|||
|
"balance[>]": 1000,
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
// 嵌套条件
|
|||
|
correctUsers4 := db.Select("user", "*", common.Map{
|
|||
|
"AND": common.Map{ // ✅ 正确,嵌套条件
|
|||
|
"status": 1,
|
|||
|
"OR": common.Map{
|
|||
|
"age[<]": 30,
|
|||
|
"level": "vip",
|
|||
|
},
|
|||
|
},
|
|||
|
"ORDER": "created_time DESC",
|
|||
|
"LIMIT": 20,
|
|||
|
})
|
|||
|
`)
|
|||
|
|
|||
|
// 实际不执行查询,只是展示语法
|
|||
|
_ = db
|
|||
|
}
|
|||
|
|
|||
|
// 运行所有修正后的示例
|
|||
|
func RunAllFixedExamples() {
|
|||
|
fmt.Println("开始运行HoTimeDB所有修正后的示例...")
|
|||
|
fmt.Println("注意:实际运行时需要确保数据库连接正确,并且相关表存在")
|
|||
|
|
|||
|
// 展示语法对比
|
|||
|
SyntaxComparison()
|
|||
|
|
|||
|
fmt.Println("请根据实际环境配置数据库连接后运行相应示例")
|
|||
|
fmt.Println("所有示例代码已修正完毕,语法正确!")
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
// 运行语法对比示例
|
|||
|
RunAllFixedExamples()
|
|||
|
}
|