Cangjie-SIG/fountain ID查询映射:IdQueryMapper主键查询

【免费下载链接】fountain 一个用于服务器应用开发的综合工具库。 - 零配置文件 - 环境变量和命令行参数配置 - 约定优于配置 - 深刻利用仓颉语言特性 - 只需要开发动态链接库,fboot负责加载、初始化并运行。 【免费下载链接】fountain 项目地址: https://gitcode.com/Cangjie-SIG/fountain

痛点:主键查询的复杂性

在日常数据库操作中,主键查询是最常见且最频繁的操作之一。传统方式中,开发者需要手动编写SQL语句、处理结果集映射、处理空值异常等繁琐工作。特别是在仓颉语言(Cangjie)这种强类型语言中,类型安全和性能优化尤为重要。

你还在为这些问题烦恼吗?

  • 手动编写重复的主键查询代码
  • 处理复杂的结果集映射逻辑
  • 担心类型转换错误和空指针异常
  • 需要为不同的主键类型编写不同的查询逻辑

一文解决所有问题! 本文将深入解析Cangjie-SIG/fountain中的IdQueryMapper组件,让你掌握高效、安全的主键查询技术。

IdQueryMapper核心架构

IdQueryMapper是fountain ORM框架中的核心组件,专门用于处理基于主键的查询操作。它继承自FieldQueryMapper,提供了类型安全的主键映射能力。

类层次结构

mermaid

核心特性

特性 描述 优势
类型安全 泛型参数ID和O确保编译时类型检查 避免运行时类型错误
自动映射 自动处理结果集到对象的映射 减少手动编码工作量
空值处理 内置Option类型处理空值情况 防止空指针异常
性能优化 缓存列信息和结果数据 提升查询性能
扩展性 支持各种主键数据类型 适应不同业务场景

核心API详解

构造函数

public class IdQueryMapper<ID, O> <: FieldQueryMapper<ID, O> where ID <: Hashable & Equatable<ID> {
    public init(
        dataType!: DataType = Int64DataType(false, 'id'),
        putter!: (O, ID) -> Unit
    ) {
        super(dataType: dataType, putter: putter)
    }
}

参数说明:

  • dataType: 数据类型,默认为非空的Int64类型,列名为'id'
  • putter: 设置器函数,用于将主键值设置到目标对象中

主要方法

1. populate方法 - 结果集填充
public func populate(result: QueryResultWrap, o: O): O {
    if (let Some(id) <- super.get<ID>(result)) {
        putter(o, id)
    }
    o
}

该方法从查询结果中提取主键值,并通过putter函数设置到目标对象中。

2. id方法 - 直接获取主键值
public func id(result: QueryResultWrap): ID {
    super.get<ID>(result).getOrThrow()
}

直接返回查询结果中的主键值,如果值为空则抛出异常。

3. isId属性 - 标识为主键映射器
protected prop isId: Bool {
    get() {
        true
    }
}

标识该映射器为主键映射器,用于QueryMappers中的特殊处理。

数据类型支持

IdQueryMapper支持多种数据类型,通过DataType体系提供类型安全的映射:

数据类型类 对应Cangjie类型 描述
Int64DataType Int64 64位整数,常用作主键
UInt64DataType UInt64 无符号64位整数
Int32DataType Int32 32位整数
StringDataType String 字符串类型主键
UUIDDataType UUID UUID类型主键

数据类型使用示例

// 使用Int64作为主键类型
let idMapper = IdQueryMapper<Int64, User>(
    dataType: Int64DataType(false, 'user_id'),
    putter: { user, id => user.id = id }
)

// 使用String作为主键类型  
let stringIdMapper = IdQueryMapper<String, Product>(
    dataType: StringDataType(false, 'product_code'),
    putter: { product, code => product.code = code }
)

实战应用示例

示例1:用户实体主键查询

// 定义用户实体
public class User {
    public var id: Int64
    public var name: String
    public var email: String
    
    public init() {}
}

// 创建主键映射器
let useridMapper = IdQueryMapper<Int64, User>(
    dataType: Int64DataType(false, 'id'),
    putter: { user, id => user.id = id }
)

// 在QueryMappers中使用
let userMappers = QueryMappers<User>(
    mappers: [
        useridMapper,
        FieldQueryMapper<String, User>(
            dataType: StringDataType(false, 'name'),
            putter: { user, name => user.name = name }
        ),
        FieldQueryMapper<String, User>(
            dataType: StringDataType(false, 'email'), 
            putter: { user, email => user.email = email }
        )
    ],
    creator: { User() }
)

// 执行查询
let result = sqlExecutor.query("SELECT id, name, email FROM users WHERE id = ?", params: [userId])
let user = userMappers.one(result)

示例2:复合查询映射器配置

// 自动生成的查询映射器配置
public class UserQueryMappers {
    public static prop queryMappers: QueryMappers<User> {
        get() {
            QueryMappers<User>(
                mappers: [
                    IdQueryMapper<Int64, User>(
                        dataType: Int64DataType(false, 'id'),
                        putter: { user, id => user.id = id }
                    ),
                    FieldQueryMapper<String, User>(
                        dataType: StringDataType(false, 'name'),
                        putter: { user, name => user.name = name }
                    ),
                    FieldQueryMapper<String, User>(
                        dataType: StringDataType(false, 'email'),
                        putter: { user, email => user.email = email }
                    )
                ],
                creator: { User() }
            )
        }
    }
}

高级特性与最佳实践

1. 类型约束保障安全

IdQueryMapper要求主键类型实现Hashable & Equatable<ID>接口,这确保了:

  • 主键值可以作为Map的键使用
  • 支持相等性比较
  • 适用于分组查询等高级场景

2. 空值安全处理

通过Option类型和getOrThrow方法,提供了完善的空值处理机制:

// 安全的主键获取
let userId: Int64 = idMapper.id(result)  // 如果为空会抛出异常

// 安全的可选获取
if (let Some(userId) <- idMapper.get<Int64>(result)) {
    // 处理有值的情况
}

3. 性能优化策略

  • 列信息缓存: QueryResultWrap缓存列名到索引的映射,避免重复计算
  • 结果数据缓存: 使用ArrayList缓存查询结果,减少数据库访问次数
  • 类型转换优化: 内置数据类型系统避免反射开销

4. 错误处理机制

try {
    let user = userMappers.one(result)
    match user {
        case Some(u) => processUser(u)
        case None => log.warn("User not found")
    }
} catch (e: TypeCastException) {
    log.error("Type conversion error: ${e.message}")
} catch (e: Exception) {
    log.error("Query failed: ${e.message}")
}

常见问题解决方案

Q1: 如何处理复合主键?

对于复合主键场景,可以使用GroupedQueryMapper结合多个IdQueryMapper:

let compositeMapper = GroupedQueryMapper<User>(
    mappers: [
        IdQueryMapper<Int64, User>(/* 第一部分主键 */),
        IdQueryMapper<String, User>(/* 第二部分主键 */)
    ]
)

Q2: 自定义主键类型如何支持?

只要自定义类型实现Hashable和Equatable接口即可:

public class CustomId : Hashable, Equatable<CustomId> {
    public let value: String
    
    public func hash(into hasher: inout Hasher) {
        hasher.combine(value)
    }
    
    public func equals(other: CustomId): Bool {
        value == other.value
    }
}

// 使用自定义主键类型
let customIdMapper = IdQueryMapper<CustomId, Entity>(/* ... */)

Q3: 性能调优建议

  1. 批量查询: 使用list()方法代替多次one()调用
  2. 索引优化: 确保数据库表的主键索引正确建立
  3. 连接池: 合理配置数据库连接池参数
  4. 缓存策略: 对热点数据实施缓存机制

总结与展望

IdQueryMapper作为fountain ORM框架的核心组件,提供了强大而灵活的主键查询能力。通过类型安全的泛型设计、完善的错误处理机制和性能优化策略,它极大地简化了数据库主键操作。

读完本文你能得到:

  • ✅ 掌握IdQueryMapper的核心原理和使用方法
  • ✅ 学会处理各种类型的主键查询场景
  • ✅ 了解性能优化和错误处理的最佳实践
  • ✅ 能够解决实际开发中的主键查询问题

随着fountain框架的持续发展,IdQueryMapper将继续增强对新型数据库的支持、提供更丰富的查询优化特性,为仓颉语言开发者提供更强大的ORM解决方案。

下一步学习建议:

  • 探索GroupedQueryMapper进行分组查询
  • 学习NestQueryMapper处理嵌套对象映射
  • 了解SqlExecutor的完整查询能力

如果本文对你有帮助,请点赞/收藏/关注三连支持! 下期我们将深入解析fountain的GroupedQueryMapper分组查询机制。

【免费下载链接】fountain 一个用于服务器应用开发的综合工具库。 - 零配置文件 - 环境变量和命令行参数配置 - 约定优于配置 - 深刻利用仓颉语言特性 - 只需要开发动态链接库,fboot负责加载、初始化并运行。 【免费下载链接】fountain 项目地址: https://gitcode.com/Cangjie-SIG/fountain

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐