rat_quickdb
🚀 强大的跨数据库ODM库,支持SQLite、PostgreSQL、MySQL、MongoDB的统一接口
✨ 核心特性
- 🎯 自动索引创建: 基于模型定义自动创建表和索引,无需手动干预
- 🗄️ 多数据库支持: SQLite、PostgreSQL、MySQL、MongoDB
- 🔗 统一API: 一致的接口操作不同数据库
- 🔒 SQLite布尔值兼容: 自动处理SQLite布尔值存储差异,零配置兼容
- 🏊 连接池管理: 高效的连接池和无锁队列架构
- ⚡ 异步支持: 基于Tokio的异步运行时
- 🧠 智能缓存: 内置缓存支持(基于rat_memcache),支持TTL过期和回退机制
- 🆔 多种ID生成策略: AutoIncrement、UUID、Snowflake、ObjectId、Custom前缀
- 📝 日志控制: 由调用者完全控制日志初始化,避免库自动初始化冲突
- 🐍 Python绑定: 可选Python API支持
- 📋 任务队列: 内置异步任务队列系统
- 🔍 类型安全: 强类型模型定义和验证
- 📋 存储过程: 跨数据库的统一存储过程API,支持多表JOIN和聚合查询
🔄 版本变更说明
v0.3.6 (当前版本) - 存储过程虚拟表系统
⚠️ 重要变更:连接池配置参数单位变更
v0.3.6 对连接池配置进行了重大改进,所有超时参数现在使用秒为单位:
// v0.3.6 新写法(推荐)
let pool_config = builder
.connection_timeout // 30秒(之前是5000毫秒)
.idle_timeout // 300秒(之前是300000毫秒)
.max_lifetime // 1800秒(之前是1800000毫秒)
.max_retries // 新增:最大重试次数
.retry_interval_ms // 新增:重试间隔(毫秒)
.keepalive_interval_sec // 新增:保活间隔(秒)
.health_check_timeout_sec // 新增:健康检查超时(秒)
.build?;
新功能:
- 🎯 存储过程虚拟表系统:跨四种数据库的统一存储过程API
- 🔗 多表JOIN支持:自动生成JOIN语句和聚合管道
- 📊 聚合查询优化:自动GROUP BY子句生成(SQL数据库)
- 🧠 类型安全存储过程:编译时验证和类型检查
📦 安装
在Cargo.toml中添加依赖:
[]
= "0.3.6"
🔧 特性控制
rat_quickdb 使用 Cargo 特性来控制不同数据库的支持和功能。默认情况下只包含核心功能,你需要根据使用的数据库类型启用相应的特性:
[]
= { = "0.3.6", = [
"sqlite-support", # 支持SQLite数据库
"postgres-support", # 支持PostgreSQL数据库
"mysql-support", # 支持MySQL数据库
"mongodb-support", # 支持MongoDB数据库
] }
可用特性列表
| 特性名称 | 描述 | 默认启用 |
|---|---|---|
sqlite-support |
SQLite数据库支持 | ❌ |
postgres-support |
PostgreSQL数据库支持 | ❌ |
mysql-support |
MySQL数据库支持 | ❌ |
mongodb-support |
MongoDB数据库支持 | ❌ |
melange-storage |
已弃用:L2缓存功能已内置在rat_memcache中 | ❌ |
python-bindings |
Python API绑定 | ❌ |
full |
启用所有数据库支持 | ❌ |
按需启用特性
仅使用SQLite:
[]
= { = "0.3.6", = ["sqlite-support"] }
使用PostgreSQL:
[]
= { = "0.3.6", = ["postgres-support"] }
使用所有数据库:
[]
= { = "0.3.6", = ["full"] }
L2缓存配置注意事项:
- L2缓存功能已内置在
rat_memcache中,无需额外特性 - L2缓存需要磁盘空间用于缓存持久化
- 配置示例见下面的"缓存配置"部分
运行示例
不同的示例需要不同的特性支持:
# 基础模型定义示例
# 复杂查询示例
# 分页查询示例
# 特殊类型测试示例
# ID生成策略示例
# 手动表管理示例
# 其他数据库示例
⚠️ 重要架构说明
ODM层使用要求 (v0.3.0+)
从v0.3.0版本开始,强制使用define_model!宏定义模型,不再允许使用普通结构体进行数据库操作。
所有数据库操作必须通过以下方式:
- 推荐:使用模型API
use *;
use ModelOperations;
// 定义模型
define_model!
// 创建和保存
let user = User ;
let user_id = user.save.await?;
// 查询
let found_user = find_by_id.await?;
- 备选:使用ODM API
use *;
// 通过add_database添加数据库配置
let config = builder
.db_type
.connection
.alias
.build?;
add_database.await?;
// 使用ODM操作数据库
let mut user_data = new;
user_data.insert;
create.await?;
- 禁止的用法
// ❌ 错误:不再允许直接访问连接池管理器
// let pool_manager = get_global_pool_manager();
// let pool = pool_manager.get_connection_pools().get("main");
这种设计确保了:
- 架构完整性: 统一的数据访问层
- 安全性: 防止直接操作底层连接池导致的资源泄漏
- 一致性: 所有操作都经过相同的ODM层处理
- 维护性: 统一的错误处理和日志记录
📋 从旧版本升级
从 v0.2.x 升级到 v0.3.0
v0.3.0 是一个重大变更版本,包含破坏性更改。请查看详细的迁移指南。
主要变更:
- ✅ 强制使用
define_model!宏定义模型 - ✅ 消除动态表结构推断的"保姆设置"问题
- ✅ 提供更明确的类型安全和字段定义
- ✅ 修复重大架构Bug
从 v0.3.1 升级到 v0.3.2+
🚨 破坏性变更:便捷函数必须显式指定ID策略
从v0.3.2版本开始,所有数据库配置的便捷函数(sqlite_config、postgres_config、mysql_config、mongodb_config)现在要求必须显式传入id_strategy参数。
变更原因:
- 消除硬编码的"保姆设置",确保用户完全控制ID生成策略
- 所有数据库统一默认使用
AutoIncrement策略 - 避免不同数据库有不同默认策略导致的混淆
API变更:
// v0.3.1及之前(已移除)
let config = sqlite_config?;
// v0.3.2+(新API)
let config = sqlite_config?;
迁移指南:
- 推荐方式:迁移到构建器模式,获得更好的类型安全性和一致性
// 推荐使用构建器模式替代便捷函数:
let config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy
.build?;
// PostgreSQL使用UUID(PostgreSQL推荐)
let config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy
.build?;
- 临时兼容:如果必须暂时维护现有代码,请添加必需的
IdStrategy参数,但尽快规划迁移到构建器模式
影响范围:
- 所有使用便捷函数配置数据库的代码
- 使用
mongodb_config_with_builder的代码(已移除重复函数) - 依赖特定数据库默认ID策略的应用
这个变更确保了配置的一致性和用户控制权,符合"不做保姆设置"的设计原则。
🚀 快速开始
基本使用
查看 examples/model_definition.rs 了解完整的模型定义和使用方法。
ID生成策略示例
查看 examples/id_strategy_test.rs 了解不同ID生成策略的使用方法。
数据库适配器示例
- SQLite:
examples/model_definition.rs(运行时使用--features sqlite-support) - PostgreSQL:
examples/model_definition_pgsql.rs - MySQL:
examples/model_definition_mysql.rs - MongoDB:
examples/model_definition_mongodb.rs
模型定义(推荐方式)
查看 examples/model_definition.rs 了解完整的模型定义、CRUD操作和复杂查询示例。
字段类型和验证
查看 examples/model_definition.rs 中包含的字段类型定义和验证示例。
索引管理
索引会根据模型定义自动创建,无需手动管理。参考 examples/model_definition.rs 了解索引定义方式。
🔒 SQLite布尔值兼容性
SQLite数据库将布尔值存储为整数(0和1),这可能导致serde反序列化错误。rat_quickdb提供了多种解决方案:
方案1: sqlite_bool_field() - 推荐(零配置)
use *;
define_model!
方案2: 手动serde属性 + 通用反序列化器
use *;
use Deserialize;
define_model!
方案3: 传统方式(需要手动处理)
// 对于已有代码,可以使用传统boolean_field()
// 但需要确保数据源中的布尔值格式正确
define_model!
反序列化器选择指南
deserialize_bool_from_any(): 支持整数、布尔值、字符串 "true"/"false"deserialize_bool_from_int(): 支持整数和布尔值sqlite_bool_field(): 自动选择最佳反序列化器
迁移指南
从传统boolean_field()迁移到sqlite_bool_field():
// 之前(可能有兼容性问题)
is_active: boolean_field,
// 之后(完全兼容)
is_active: sqlite_bool_field,
🆔 ID生成策略
rat_quickdb支持多种ID生成策略,满足不同场景的需求:
AutoIncrement(自增ID)- 默认推荐
builder
.id_strategy
.build?
// 便捷函数使用
let config = sqlite_config?;
UUID(通用唯一标识符)- PostgreSQL推荐
builder
.id_strategy
.build?
// 便捷函数使用
let config = postgres_config?;
⚠️ PostgreSQL UUID策略特殊要求
重要提醒:PostgreSQL对类型一致性有严格要求,如果使用UUID策略:
- 主键表:ID字段将为UUID类型
- 关联表:所有外键字段也必须为UUID类型
- 类型匹配:不允许UUID类型与其他类型进行关联
示例:
// 用户表使用UUID ID
define_model!
// 订单表的外键也必须使用UUID类型
define_model!
解决方案:
- 对于新项目:PostgreSQL推荐全面使用UUID策略
- 对于现有项目:可以使用
IdStrategy::Custom手动生成UUID字符串作为兼容方案 - 混合策略:主表使用UUID,关联表也必须使用UUID,保持类型一致性
✨ PostgreSQL UUID自动转换功能
从v0.3.4版本开始,PostgreSQL适配器支持UUID字段的自动转换,让用户可以使用字符串UUID进行查询操作。
功能特点:
- 自动转换:查询时传入字符串UUID,适配器自动转换为UUID类型
- 严格验证:无效UUID格式直接报错,不做容错修复
- 用户友好:保持API一致性,无需手动转换UUID类型
- 类型安全:确保数据库层面的UUID类型一致性
使用示例:
// 用户模型定义(注意:结构体中用String,字段定义中用uuid_field)
define_model!
// 文章模型,author_id为UUID外键
define_model!
// 查询:直接使用字符串UUID,自动转换!
let conditions = vec!;
let articles = find.await?;
// PostgreSQL适配器自动将字符串转换为UUID类型进行查询
⚠️ 反直觉的设计要求(重要!)
当前限制:使用UUID策略时,模型定义存在一个反直觉的设计要求:
define_model!
为什么会这样?
- Rust类型系统限制:宏系统在生成模型时需要统一的基础类型
- 数据库类型映射:
uuid_field()告诉适配器创建UUID数据库列 - 查询转换:运行时字符串UUID自动转换为UUID数据库类型
正确用法:
- ✅ 结构体字段:始终使用
String类型 - ✅ 字段定义:UUID字段使用
uuid_field(),其他字段使用对应函数 - ✅ 查询操作:直接使用
DataValue::String("uuid-string"),自动转换 - ✅ 类型安全:PostgreSQL数据库层面保持UUID类型一致性
错误用法:
- ❌ 结构体中使用
uuid::Uuid类型(编译错误) - ❌ UUID字段使用
string_field()定义(失去UUID类型支持) - ❌ 混用不同数据库的UUID策略(类型不匹配)
暂时无法解决的原因:
- Rust宏系统的类型推导限制
- 需要保持与现有代码的向后兼容
- 跨数据库的统一API设计要求
未来改进方向:
- v0.4.0计划引入更直观的类型安全的UUID字段定义
- 考虑使用编译时类型推导减少这种不一致性
- 提供更清晰的编译时错误提示
Snowflake(雪花算法)
builder
.id_strategy
.build?
ObjectId(MongoDB风格)
builder
.id_strategy
.build?
Custom(自定义前缀)
builder
.id_strategy
.build?
🔄 ObjectId跨数据库处理
rat_quickdb为ObjectId策略提供了跨数据库的一致性处理,确保在不同数据库后端都能正常工作。
存储方式差异
MongoDB:
- 存储为原生
ObjectId类型 - 查询时返回MongoDB原生ObjectId对象
- 性能最优,支持MongoDB所有ObjectId特性
其他数据库(SQLite、PostgreSQL、MySQL):
- 存储为24位十六进制字符串(如:
507f1f77bcf86cd799439011) - 查询时返回字符串格式的ObjectId
- 保持与MongoDB ObjectId格式的兼容性
使用示例
// MongoDB - 原生ObjectId支持
let config = mongodb_config?;
// SQLite/PostgreSQL/MySQL - 字符串格式ObjectId
let config = sqlite_config?;
模型定义
ObjectId策略在模型定义中统一使用String类型:
define_model!
查询和操作
// 创建文档
let doc = Document ;
let doc_id = doc.save.await?;
// 查询文档
let found_doc = find_by_id.await?;
// 注意:ObjectId为24位十六进制字符串格式
assert_eq!; // 其他数据库
// 在MongoDB中,这将是一个原生ObjectId对象
类型转换处理
rat_quickdb自动处理ObjectId在不同数据库中的类型转换:
- 保存时:自动生成ObjectId格式(字符串或原生对象)
- 查询时:保持原格式返回,框架内部处理转换
- 迁移时:数据格式在不同数据库间保持兼容
性能考虑
- MongoDB:原生ObjectId性能最优,支持索引优化
- 其他数据库:字符串索引性能良好,长度固定(24字符)
- 跨数据库:统一的字符串格式便于数据迁移和同步
这种设计确保了ObjectId策略在所有支持的数据库中都能一致工作,同时充分利用各数据库的原生特性。
🧠 缓存配置
基本缓存配置(仅L1内存缓存)
use ;
let cache_config = CacheConfig ;
builder
.cache
.build?
L1+L2缓存配置(内置L2缓存支持)
use ;
use PathBuf;
let cache_config = CacheConfig ;
builder
.cache
.build?
L2缓存特性说明:
- L2缓存功能已内置在
rat_memcache中,无需额外特性 - 需要磁盘空间存储缓存数据
- 适合缓存大量数据或需要持久化的场景
- 只需在
CacheConfig中配置l2_config即可启用L2缓存
缓存统计和管理
// 获取缓存统计信息
let stats = get_cache_stats.await?;
println!;
println!;
// 清理缓存
clear_cache.await?;
clear_all_caches.await?;
📝 日志控制
rat_quickdb现在完全由调用者控制日志初始化:
use ;
// 调用者负责初始化日志系统
let logger = new
.with_level
.with_file
.build;
logger.init.expect;
// 然后初始化rat_quickdb(不再自动初始化日志)
init;
🔧 数据库配置
推荐方式:使用构建器模式
推荐:使用DatabaseConfig::builder()模式,提供完整的配置控制和类型安全:
use *;
use ;
let pool_config = builder
.max_connections
.min_connections
.connection_timeout // 秒
.idle_timeout // 秒
.max_lifetime // 秒
.max_retries
.retry_interval_ms
.keepalive_interval_sec
.health_check_timeout_sec
.build?;
// SQLite 配置
let sqlite_config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy // 推荐策略
.build?;
// PostgreSQL 配置
let postgres_config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy // PostgreSQL推荐UUID策略
.build?;
// MySQL 配置
let mysql_config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy // MySQL推荐自增策略
.build?;
// MongoDB 配置
let mongodb_config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy // MongoDB推荐ObjectId策略
.build?;
// 添加到连接池管理器
add_database.await?;
add_database.await?;
add_database.await?;
add_database.await?;
高级MongoDB配置
use *;
use ;
let tls_config = TlsConfig ;
let zstd_config = ZstdConfig ;
let mongodb_builder = new
.with_auth
.with_auth_source
.with_direct_connection
.with_tls_config
.with_zstd_config;
let advanced_mongodb_config = builder
.db_type
.connection
.pool_config
.alias
.id_strategy
.build?;
add_database.await?;
🚨 即将废弃的便捷函数(不推荐使用)
重要警告:以下便捷函数已标记为废弃,将在v0.4.0版本中移除。请使用上面推荐的构建器模式。
// 🚨 即将废弃 - 请勿在新项目中使用
// 这些函数存在API不一致性和硬编码问题
// 废弃的SQLite配置
let config = sqlite_config?;
// 废弃的PostgreSQL配置
let config = postgres_config?;
// 废弃的MySQL配置
let config = mysql_config?;
// 废弃的MongoDB配置
let config = mongodb_config?;
废弃原因:
- ❌ API不一致性:不同数据库的便捷函数参数不统一
- ❌ 硬编码默认值:违背"不做保姆设置"的设计原则
- ❌ 功能限制:无法支持高级配置选项
- ❌ 维护困难:重复代码增加维护成本
推荐替代方案:
- ✅ 构建器模式:类型安全、配置完整、API统一
- ✅ 完全控制:用户完全控制所有配置选项
- ✅ 扩展性强:支持所有数据库的高级特性
- ✅ 类型安全:编译时检查配置正确性
ID策略推荐
根据数据库特性选择最适合的ID策略:
| 数据库 | 推荐策略 | 备选策略 | 说明 |
|---|---|---|---|
| SQLite | AutoIncrement | ObjectId | AutoIncrement原生支持,性能最佳 |
| PostgreSQL | UUID | AutoIncrement | UUID原生支持,类型安全 |
| MySQL | AutoIncrement | ObjectId | AutoIncrement原生支持,性能最佳 |
| MongoDB | ObjectId | AutoIncrement | ObjectId原生支持,MongoDB生态标准 |
重要提醒:PostgreSQL使用UUID策略时,所有关联表的外键字段也必须使用UUID类型以保持类型一致性。
🛠️ 核心API
数据库管理
init()- 初始化库add_database(config)- 添加数据库配置remove_database(alias)- 移除数据库配置get_aliases()- 获取所有数据库别名set_default_alias(alias)- 设置默认数据库别名
模型操作(推荐)
// 保存记录
let user_id = user.save.await?;
// 查询记录
let found_user = find_by_id.await?;
let users = find.await?;
// 更新记录
let mut updates = new;
updates.insert;
let updated = user.update.await?;
// 删除记录
let deleted = user.delete.await?;
ODM操作(底层接口)
create(collection, data, alias)- 创建记录find_by_id(collection, id, alias)- 根据ID查找find(collection, conditions, options, alias)- 查询记录update(collection, id, data, alias)- 更新记录delete(collection, id, alias)- 删除记录count(collection, query, alias)- 计数exists(collection, query, alias)- 检查是否存在
🏗️ 架构特点
rat_quickdb采用现代化架构设计:
- 无锁队列架构: 避免直接持有数据库连接的生命周期问题
- 模型自动注册: 首次使用时自动注册模型元数据
- 自动索引管理: 根据模型定义自动创建表和索引
- 跨数据库适配: 统一的接口支持多种数据库类型
- 异步消息处理: 基于Tokio的高效异步处理
🔄 工作流程
应用层 → 模型操作 → ODM层 → 消息队列 → 连接池 → 数据库
↑ ↓
└────────────── 结果返回 ←────────────────┘
📊 性能特性
- 连接池管理: 智能连接复用和管理
- 异步操作: 非阻塞的数据库操作
- 批量处理: 支持批量操作优化
- 缓存集成: 内置缓存减少数据库访问
- 压缩支持: MongoDB支持ZSTD压缩
🎯 支持的字段类型
integer_field- 整数字段(支持范围和约束)string_field- 字符串字段(支持长度限制,可设置大长度作为长文本使用)float_field- 浮点数字段(支持范围和精度)boolean_field- 布尔字段datetime_field- 日期时间字段uuid_field- UUID字段json_field- JSON字段array_field- 数组字段list_field- 列表字段(array_field的别名)dict_field- 字典/对象字段(基于Object类型)reference_field- 引用字段(外键)
📝 索引支持
- 唯一索引:
unique()约束 - 复合索引: 多字段组合索引
- 普通索引: 基础查询优化索引
- 自动创建: 基于模型定义自动创建
- 跨数据库: 支持所有数据库类型的索引
🌟 版本信息
当前版本: 0.3.4
支持Rust版本: 1.70+
重要更新: v0.3.0 强制使用define_model!宏定义模型,修复重大架构问题,提升类型安全性!
📄 许可证
本项目采用 LGPL-v3 许可证。
🤝 贡献
欢迎提交Issue和Pull Request来改进这个项目!
📚 技术文档
数据库限制说明
- MySQL 限制说明 - 必须遵守的索引长度限制
- PostgreSQL 限制说明 - 必须遵守的UUID类型处理要求
其他文档
📞 联系方式
如有问题或建议,请通过以下方式联系:
- 创建Issue: GitHub Issues
- 邮箱: oldmos@gmail.com