# vload **Repository Path**: virtual-moon/vload ## Basic Information - **Project Name**: vload - **Description**: 这个包提供了一个灵活的值加载器,用于动态加载和填充结构体字段。主要用于批量加载外键或关联数据,减少数据库查询次数,提高性能。 - **Primary Language**: Go - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2024-12-03 - **Last Updated**: 2026-01-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: Go语言 ## README # ValueLoader Package [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 这个包提供了一个灵活的值加载器,用于动态加载和填充结构体字段。主要用于批量加载关联数据,减少数据库查询次数,提高性能。 ## 安装 使用以下命令安装: ```bash go get gitee.com/virtual-moon/vload ``` ## 版本要求 - Go 1.18 或更高版本 (需要泛型支持) ## 主要特性 - 支持泛型值获取器 - 类型安全的字段映射 - 支持多分组加载 - 自动类型推断 - 支持结构体和切片(包括指针切片) - 零值字段自动跳过 - 灵活的分组机制 - 并发安全 ## 主要组件 1. `types.go` - `Pair`: 字段映射对定义 - `Getter`: 泛型值获取器 - `Loader`: 值加载器结构 2. `loader.go` - `AddMapping`: 添加字段映射 - `Load`: 主加载方法 - 字段映射验证 3. `utils.go` - 值获取器调用 - 键值收集 - 值填充 4. `quick.go` - 快速加载方法 - 数据加载实现 ## 使用示例 ### 基础用法 - 单一字段映射 ```go // 支持结构体切片 var orders []Order err := vload.LoadQuick( &orders, "GoodsId", // 源字段(用于获取值的字段) "GoodsName", // 目标字段(用于填充值的字段) func(keys []int64) (map[int64]string, error) { // 实现值获取逻辑 return namesMap, nil }, ) // 同样支持指针切片 var users []*User err := vload.LoadQuick( &users, "DeptId", // 源字段 "DeptName", // 目标字段 getDeptNames, ) ``` ### 快速用法 - 同类型多字段映射 ```go // 定义字段映射关系 fields := []vload.FieldPair{ {Source: "UserId", Target: "UserName"}, {Source: "CreatorId", Target: "CreatorName"}, {Source: "UpdaterId", Target: "UpdaterName"}, } // 使用简化版本,自动推断类型 err := vload.LoadQuickMulti( &orders, fields, func(keys []int64) (map[int64]string, error) { // 实现值获取逻辑:一次性获取所有用户名 // keys 包含了所有 UserId、CreatorId 和 UpdaterId 的值 names, err := db.QueryUserNames(keys) if err != nil { return nil, err } return names, nil }, ) // 使用完整版本,指定字段类型 err := vload.LoadQuickMultiWithType( &orders, fields, reflect.Int64, // 源字段类型 reflect.String, // 目标字段类型 getUserNames, // 值获取器 ) ``` ### 高级用法 - 多字段映射 ```go loader := vload.New() // 添加用户信息映射 loader.AddMapping("users", []vload.Pair{ { SourceField: "UserId", // 源字段 TargetField: "UserName", // 目标字段 }, }, getUserNames) // 添加商品信息映射 loader.AddMapping("goods", []vload.Pair{ { SourceField: "GoodsId", // 源字段 TargetField: "GoodsName", // 目标字段 }, }, getGoodsNames) // 执行加载 err := loader.Load(&data) ``` ## 常见使用场景 1. 批量加载关联数据 ```go type Order struct { UserId int64 // 源字段 UserName string // 目标字段 GoodsId int64 // 源字段 GoodsName string // 目标字段 } ``` 2. 字段映射和转换 ```go type UserView struct { Code string // 源字段 UserInfo User // 目标字段 } ``` 3. 多级数据填充 ```go type Department struct { ManagerId int64 // 源字段 ManagerName string // 目标字段 ParentId int64 // 源字段 ParentName string // 目标字段 } ``` 4. 系统统一处理 可在系统里创建一个通用统一的键值处理,如ERP系统,可以创建一个整个系统规范的字段加载器,有需要用到的数据可直接调用处理。 ```go var userLoad *vload.Loader var goodsLoad *vload.Loader func init() { userLoad = vload.New() userLoad.AddMapping("user", []vload.Pair{ {SourceField: "CreatedId", TargetField: "CreatedBy"}, {SourceField: "UpdatedId", TargetField: "UpdatedBy"}, {SourceField: "CheckedId", TargetField: "CheckedBy"}, }, func(keys []int64) (map[int64]string, error) { return GetUserNames(keys) }) goodsLoad = vload.New() goodsLoad.AddMapping("goods", []vload.Pair{ {SourceField: "GoodsId", TargetField: "GoodsName"}, }, func(keys []int64) (map[int64]string, error) { return GetGoodsNames(keys) }) } ``` ```go userLoad.Load(&orders) ``` ```go userLoad.Load(&orderDetails) ``` ## 性能优化建议 1. 合理分组:相同数据源的字段放在同一组,减少查询次数 2. 使用合适的切片容量:预估数据量,避免频繁扩容 3. 实现高效的值获取器:可以使用缓存或批量查询优化性能 ## 注意事项 1. 指定正确的字段类型:确保源字段和目标字段的类型匹配 2. 处理错误返回:值获取器返回的错误需要妥善处理 3. 避免循环依赖:设计映射关系时注意避免循环引用 ## 贡献 欢迎提交 Issue 和 Pull Request 来改进这个包。