sqlxplus
A production-ready, cross-database (MySQL / PostgreSQL / SQLite) advanced database toolkit for Rust — providing CRUD operations, pagination, dynamic query building, CRUD builders, and code generation — all while preserving SQLx's native performance and SQL flexibility.
Features
- Cross-Database: Supports MySQL, PostgreSQL, and SQLite — switch by changing the connection URL
- Zero-Cost Abstractions: All operations use native SQLx commands, no runtime abstraction overhead
- Developer Experience: ORM-like APIs (
Modeltrait,derive(CRUD)macro,QueryBuilder), minimizing boilerplate - Extensible: Custom SQL, transactions, raw query access; easy to extend to new databases
- Type-Safe: Parameterized SQL, compile-time checks wherever possible, no string concatenation for user inputs
- Code Generation: CLI tool to auto-generate models + CRUD + tests from database schemas
Quick Start
Installation
[]
= { = "0.2.7", = ["mysql"] }
= { = "0.8.6", = ["runtime-tokio-native-tls", "chrono", "mysql"] }
= { = "1.40", = ["full"] }
Choose features based on your database:
| Database | Feature |
|---|---|
| MySQL | "mysql" |
| PostgreSQL | "postgres" |
| SQLite | "sqlite" |
You can also enable multiple databases simultaneously: features = ["mysql", "postgres", "sqlite"]
Basic Example
use ;
// Define a model
async
Architecture
sqlx-plus/
├─ core/ # Core library (sqlxplus) — published on crates.io
│ └─ src/
│ ├─ traits.rs # Model + Crud trait definitions
│ ├─ crud.rs # Generic CRUD implementations (find, insert, update, delete, paginate)
│ ├─ builder/ # Query & CRUD Builder system
│ │ ├─ query_builder.rs # Dynamic WHERE clause builder
│ │ ├─ update_builder.rs # Selective field update builder
│ │ ├─ insert_builder.rs # Selective field insert builder
│ │ └─ delete_builder.rs # Conditional delete builder
│ ├─ db_pool.rs # Unified connection pool (DbPool)
│ ├─ transaction.rs # Transaction management (flat + nested via savepoints)
│ ├─ database_info.rs # DB-specific info abstraction (placeholder, identifier escaping)
│ ├─ database_type.rs # Automatic DB type inference from Pool/Transaction
│ ├─ executor.rs # DbExecutor trait for pool/transaction unification
│ ├─ macros_api.rs # Metadata structs used by proc-macros (FieldMeta, ModelMeta)
│ ├─ error.rs # Error types (SqlxPlusError)
│ └─ utils.rs # Utility functions
├─ derive/ # Proc-macro crate (sqlxplus-derive) — published on crates.io
│ └─ src/lib.rs # #[derive(ModelMeta)] and #[derive(CRUD)] macros
├─ cli/ # Code generator (sqlxplus-cli) — published on crates.io
│ └─ src/
│ ├─ main.rs # CLI entry point (generate / sql commands)
│ ├─ database.rs # DB schema introspection
│ ├─ generator.rs # Rust model code generator
│ └─ sql_generator.rs # SQL DDL generator from Rust models
└─ examples/ # Example projects
├─ mysql_example/
├─ postgres_example/
├─ sqlite_example/
└─ test_models/
Detailed Documentation
1. Defining Models
Use ModelMeta and CRUD derive macros to auto-generate CRUD operations:
Model attributes:
| Attribute | Description | Required |
|---|---|---|
table |
Database table name | ✅ Yes |
pk |
Primary key field name (default: "id") |
No |
soft_delete |
Soft delete field name | No |
table_comment |
Table comment (for SQL generation) | No |
Field attributes (via #[column(...)]):
| Attribute | Description |
|---|---|
primary_key |
Marks as primary key |
auto_increment |
Auto-increment field |
not_null |
NOT NULL constraint |
default |
Default value (SQL expression, e.g. "0", "CURRENT_TIMESTAMP") |
length |
Field length (for VARCHAR, etc.) |
unique |
Unique constraint |
index |
Creates an index on this field |
combine_index |
Combined index, format: "idx_name:order" |
soft_delete |
Marks as soft delete field |
comment |
Column comment |
2. Soft Delete
Enable soft delete by specifying the soft_delete attribute:
// Soft delete (sets is_deleted = 1)
delete_by_id.await?;
// Queries automatically filter deleted records
let post = find_by_id.await?; // Returns None
// Force hard delete
hard_delete_by_id.await?;
3. CRUD Operations
Create
let user = User ;
let id = user.insert.await?;
Read
// Find by ID
let user = find_by_id.await?;
// Find by multiple IDs
let users = find_by_ids.await?;
// Find one with QueryBuilder
let builder = new.and_eq;
let user = find_one.await?;
// Find all (max 1000 records)
let users = find_all.await?;
Update
// Patch semantics: None fields are NOT updated (preserves DB values)
let mut user = find_by_id.await?.unwrap;
user.name = Some;
user.email = None; // email will NOT be changed
user.update.await?;
// Reset semantics: None fields are reset to database defaults
user.update_with_none.await?;
Delete
// Auto-select hard/soft delete based on model configuration
delete_by_id.await?;
// Force hard delete
hard_delete_by_id.await?;
// Force soft delete (requires soft_delete configuration)
soft_delete_by_id.await?;
4. QueryBuilder
QueryBuilder provides safe, flexible dynamic query construction:
use QueryBuilder;
// Basic query
let builder = new
.and_eq
.and_like
.order_by; // false = DESC
let users = find_all.await?;
// Condition grouping
let builder = new
.and_group
.and_gt;
// SQL: WHERE (status = 1 OR status = 2) AND age > 18
// Complex query
let builder = new
.and_in
.and_between
.and_is_not_null
.order_by
.limit
.offset;
Available methods:
| Category | Methods |
|---|---|
| Comparison | and_eq, and_ne, and_gt, and_ge, and_lt, and_le |
| OR variants | or_eq, or_ne, or_gt, or_ge, or_lt, or_le |
| Pattern | and_like, and_like_prefix, and_like_suffix, and_like_exact, and_like_custom, or_like |
| Range | and_in, and_not_in, or_in, and_between, or_between |
| Null | and_is_null, and_is_not_null, or_is_null, or_is_not_null |
| Grouping | and_group, or_group |
| Aggregation | group_by, having_eq, having_ne, having_gt, having_ge, having_lt, having_le |
| Sorting | order_by |
| Limit | limit, offset |
5. CRUD Builders
For advanced insert/update/delete scenarios beyond simple CRUD, use the Builder pattern:
UpdateBuilder — Selective Field Updates
use UpdateBuilder;
// Update only specific fields
let user = User ;
let affected = new
.field
.condition
.execute
.await?;
InsertBuilder — Selective Field Inserts
use InsertBuilder;
// Insert only specified fields
let user = User ;
let id = new
.field
.field
.execute
.await?;
DeleteBuilder — Conditional Deletes
use DeleteBuilder;
// Delete with WHERE conditions
let affected = new
.condition
.execute
.await?;
6. Pagination
let builder = new
.and_eq
.order_by;
let page = paginate.await?;
println!;
println!;
println!;
println!;
println!;
7. Transactions
use Transaction;
// Basic transaction
let mut tx = begin.await?;
let id = user.insert.await?;
let mut user = find_by_id.await?.unwrap;
user.status = Some;
user.update.await?;
tx.commit.await?;
// Callback-style transaction (auto commit/rollback)
use with_transaction;
let result = with_transaction.await?;
Nested transactions (via savepoints):
use ;
with_transaction.await?;
8. Database Connection
use DbPool;
// MySQL
let pool = connect.await?;
// PostgreSQL
let pool = connect.await?;
// SQLite
let pool = connect.await?;
let pool = connect.await?; // In-memory database
9. Count
let builder = new.and_eq;
let count = count.await?;
CLI Tool — sqlxplus-cli
A bidirectional code generator: Database → Rust Model and Rust Model → SQL DDL.
Installation
Generate Rust Models from Database
# Interactive table selection
# Generate all tables
# Generate specific tables to a directory
# Preview generated code (dry run)
Generate SQL from Rust Models
# Generate MySQL DDL from a model file
# Scan directory and generate SQL for all models
See the full CLI documentation for details on options, type mappings, and advanced usage.
Feature Checklist
- ✅ CRUD operations (Create, Read, Update, Delete)
- ✅ Soft delete support
- ✅ Pagination (
paginate) - ✅ Transaction support (flat + nested via savepoints)
- ✅ Safe QueryBuilder (parameterized, no SQL injection)
- ✅ Condition grouping (AND/OR with parentheses, nested)
- ✅ GROUP BY & HAVING support
- ✅ LIMIT / OFFSET
- ✅ Multi-database support (MySQL, PostgreSQL, SQLite)
- ✅ Type-safe parameter binding
- ✅ Compile-time type checks
- ✅ Async operations
- ✅ CRUD Builders (UpdateBuilder, InsertBuilder, DeleteBuilder)
- ✅ Bidirectional code generation (DB → Rust, Rust → SQL)
Important Notes
- Field Types: Use
Option<T>wrapper fields to support NULL values and flexible update semantics - Primary Key: PK fields should typically be
Option<i64>— set toNoneon insert for auto-generation - Update Semantics:
update(): Patch —Nonefields are skipped (DB values preserved)update_with_none(): Reset —Nonefields are reset to DB defaults
- Performance: QueryBuilder uses parameterized queries, preventing SQL injection with performance comparable to hand-written SQL
- DB Type Inference: The database type is automatically inferred from the Pool/Transaction passed to each operation — no explicit type parameters needed
Examples
See the examples/ directory for complete working examples:
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
License
MIT OR Apache-2.0
sqlxplus(中文文档)
在保持 SQLx 性能与 SQL 灵活性的前提下,为 Rust 项目提供一套可生产、跨 MySQL/Postgres/SQLite 的高级数据库封装(CRUD、分页、动态查询、CRUD Builder、代码生成)。
特性
- 兼容性:支持 MySQL、Postgres、SQLite,切换仅需配置 URL
- 性能:所有底层使用 SQLx 原生命令,避免运行时抽象开销
- 开发体验:提供类似 ORM 的便捷 API(
Modeltrait、derive(CRUD)宏、QueryBuilder),减少样板代码 - 可扩展性:支持自定义 SQL、事务、原生 query 访问;易于扩展新数据库
- 安全性:SQL 参数化、编译期检查(尽可能),严禁字符串拼接用于用户输入
- 可生成:命令行工具从 schema 自动生成 model + CRUD + tests
快速开始
安装
[]
= { = "0.2.7", = ["mysql"] }
= { = "0.8.6", = ["runtime-tokio-native-tls", "chrono", "mysql"] }
= { = "1.40", = ["full"] }
根据你使用的数据库选择对应的 feature:
| 数据库 | Feature |
|---|---|
| MySQL | "mysql" |
| PostgreSQL | "postgres" |
| SQLite | "sqlite" |
或同时启用多个: features = ["mysql", "postgres", "sqlite"]
基础示例
use ;
// 定义模型
async
架构概览
sqlx-plus/
├─ core/ # 核心库(sqlxplus)- 已发布到 crates.io
│ └─ src/
│ ├─ traits.rs # Model + Crud trait 定义
│ ├─ crud.rs # 泛型 CRUD 实现(find, insert, update, delete, paginate)
│ ├─ builder/ # 查询 & CRUD Builder 系统
│ │ ├─ query_builder.rs # 动态 WHERE 条件构建器
│ │ ├─ update_builder.rs # 选择性字段更新构建器
│ │ ├─ insert_builder.rs # 选择性字段插入构建器
│ │ └─ delete_builder.rs # 条件删除构建器
│ ├─ db_pool.rs # 统一连接池(DbPool)
│ ├─ transaction.rs # 事务管理(平级 + 嵌套 savepoint)
│ ├─ database_info.rs # 数据库特性抽象(占位符、标识符转义)
│ ├─ database_type.rs # 从 Pool/Transaction 自动推断数据库类型
│ ├─ executor.rs # DbExecutor trait,统一 Pool 与 Transaction
│ ├─ macros_api.rs # 宏使用的元数据结构体(FieldMeta, ModelMeta)
│ ├─ error.rs # 错误类型(SqlxPlusError)
│ └─ utils.rs # 工具函数
├─ derive/ # proc-macro crate(sqlxplus-derive)- 已发布到 crates.io
│ └─ src/lib.rs # #[derive(ModelMeta)] 和 #[derive(CRUD)] 宏实现
├─ cli/ # 代码生成器(sqlxplus-cli)- 已发布到 crates.io
│ └─ src/
│ ├─ main.rs # CLI 入口(generate / sql 命令)
│ ├─ database.rs # 数据库 schema 自省
│ ├─ generator.rs # Rust model 代码生成器
│ └─ sql_generator.rs # 从 Rust model 生成 SQL DDL
└─ examples/ # 示例项目
├─ mysql_example/
├─ postgres_example/
├─ sqlite_example/
└─ test_models/
详细使用文档
1. 定义模型
使用 ModelMeta 和 CRUD 宏自动生成 CRUD 操作:
模型属性: table(表名,必填)、pk(主键,默认 "id")、soft_delete(逻辑删除字段)、table_comment(表注释)
字段属性 #[column(...)]:primary_key, auto_increment, not_null, default, length, unique, index, combine_index, soft_delete, comment
2. 逻辑删除
delete_by_id.await?; // 将 is_deleted 设置为 1
let post = find_by_id.await?; // 返回 None
hard_delete_by_id.await?; // 强制物理删除
3. CRUD 操作
插入(Create)
let user = User ;
let id = user.insert.await?;
查询(Read)
let user = find_by_id.await?; // 根据 ID
let users = find_by_ids.await?; // 根据多个 ID
let builder = new.and_eq;
let user = find_one.await?; // 使用 QueryBuilder
let users = find_all.await?; // 所有(最多 1000 条)
更新(Update)
// Patch 语义:Option 字段为 None 时不更新
let mut user = find_by_id.await?.unwrap;
user.name = Some;
user.email = None; // 不更新 email 字段
user.update.await?;
// Reset 语义:Option 字段为 None 时重置为数据库默认值
user.update_with_none.await?;
删除(Delete)
delete_by_id.await?; // 根据配置自动选择物理/逻辑删除
hard_delete_by_id.await?; // 强制物理删除
soft_delete_by_id.await?; // 强制逻辑删除
4. 查询构建器
use QueryBuilder;
// 基础查询
let builder = new
.and_eq
.and_like
.order_by; // false = DESC
// 条件分组
let builder = new
.and_group
.and_gt;
// SQL: WHERE (status = 1 OR status = 2) AND age > 18
// 复杂查询
let builder = new
.and_in
.and_between
.and_is_not_null
.order_by
.limit
.offset;
可用方法: 比较(and_eq/or_eq, and_ne/or_ne, and_gt/or_gt, and_ge/or_ge, and_lt/or_lt, and_le/or_le)、模糊(and_like, and_like_prefix, and_like_suffix, and_like_exact, and_like_custom, or_like)、范围(and_in/or_in, and_not_in, and_between/or_between)、空值(and_is_null/or_is_null, and_is_not_null/or_is_not_null)、分组(and_group, or_group)、聚合(group_by, having_eq/ne/gt/ge/lt/le)、排序(order_by)、限制(limit, offset)
5. CRUD Builder
提供更灵活的插入、更新、删除操作:
UpdateBuilder — 选择性字段更新
use UpdateBuilder;
let user = User ;
let affected = new
.field // 只更新 name 字段
.condition // WHERE 条件
.execute
.await?;
InsertBuilder — 选择性字段插入
use InsertBuilder;
let user = User ;
let id = new
.field
.field
.execute
.await?;
DeleteBuilder — 条件删除
use DeleteBuilder;
let affected = new
.condition
.execute
.await?;
6. 分页查询
let builder = new.and_eq.order_by;
let page = paginate.await?;
// page.total, page.page, page.size, page.pages, page.items
7. 事务支持
use Transaction;
// 手动事务
let mut tx = begin.await?;
let id = user.insert.await?;
tx.commit.await?;
// 回调式事务(自动提交/回滚)
use with_transaction;
let result = with_transaction.await?;
// 嵌套事务(通过 SAVEPOINT)
use with_mysql_nested_transaction;
with_transaction.await?;
8. 数据库连接
use DbPool;
let pool = connect.await?; // MySQL
let pool = connect.await?; // PostgreSQL
let pool = connect.await?; // SQLite
let pool = connect.await?; // 内存数据库
9. 统计查询
let builder = new.and_eq;
let count = count.await?;
CLI 工具 — sqlxplus-cli
双向代码生成器:数据库 → Rust Model 和 Rust Model → SQL DDL。
# 从数据库生成 Rust Model
# 从 Rust Model 生成 SQL DDL
详细用法请参阅 CLI 文档。
功能特性
- ✅ CRUD 操作(Create, Read, Update, Delete)
- ✅ 逻辑删除支持(soft delete)
- ✅ 分页查询(paginate)
- ✅ 事务支持(平级 + 嵌套 savepoint)
- ✅ 安全查询构建器(QueryBuilder)
- ✅ 条件分组(AND/OR with parentheses,嵌套)
- ✅ GROUP BY 和 HAVING 支持
- ✅ LIMIT/OFFSET 支持
- ✅ 多数据库支持(MySQL, PostgreSQL, SQLite)
- ✅ 类型安全的参数绑定
- ✅ 编译期类型检查
- ✅ 异步操作
- ✅ CRUD Builder(UpdateBuilder, InsertBuilder, DeleteBuilder)
- ✅ 双向代码生成(DB → Rust, Rust → SQL)
注意事项
- 字段类型:建议使用
Option<T>包装字段,以支持 NULL 值和灵活的更新语义 - 主键:主键字段通常使用
Option<i64>,插入时设为None自动生成 - 更新语义:
update(): Patch 语义,None值的字段不更新update_with_none(): Reset 语义,None值的字段重置为默认值
- 性能:查询构建器使用参数化查询,避免 SQL 注入,性能与手写 SQL 相当
- 数据库类型推断:数据库类型从传入的 Pool/Transaction 自动推断,无需显式指定类型参数
示例代码
查看 examples/ 目录获取完整的示例代码:
贡献
- Fork 仓库
- 创建功能分支 (
git checkout -b feature/my-feature) - 提交修改 (
git commit -am 'Add new feature') - 推送分支 (
git push origin feature/my-feature) - 创建 Pull Request
License
MIT OR Apache-2.0