# rust-orm **Repository Path**: olnho0808/rust-orm ## Basic Information - **Project Name**: rust-orm - **Description**: rust-orm此代码有ai自动生成 - **Primary Language**: Rust - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-08 - **Last Updated**: 2026-09-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rust-orm 轻量 MySQL 查询构建器(基于 [sqlx](https://github.com/launchbadge/sqlx)),API 风格参考 PHP `PdoDb.php`。 Rust crate 名:`rust_orm`。 --- ## 安装 ```toml # 本地路径 rust-orm = { path = "../rust-orm" } # Git rust-orm = { git = "https://gitee.com/olnho0808/rust-orm.git" } ``` 常用导入: ```rust use rust_orm::{ Config, Data, Result, Where, connect, set_debug, set_prefix, sql, transaction, P, D, }; ``` 宏也可直接写 `sql!` / `Where!` / `V!` / `transaction!`(crate 根已导出)。 --- ## 快速开始 ```rust use rust_orm::{Config, Data, Result, Where, connect, sql, transaction, P}; #[tokio::main] async fn main() -> Result<()> { connect(Config { host: "127.0.0.1".into(), database: "mydb".into(), username: "root".into(), password: "secret".into(), prefix: "app_".into(), ..Default::default() }) .await?; // 推荐:过程宏 sql! sql! { let n = P("user") .where(["id" => 1]) .update(["status" : 1]) .await?; } // 或:链式 + Where! / V! P("user") .condition(Where!(["id": 1])) .update(V!({ "status": 1 })) .await?; Ok(()) } ``` --- ## 连接与配置 ```rust use rust_orm::{Config, connect, get_pool, set_debug, set_pool, set_prefix}; connect(Config { host: "127.0.0.1".into(), port: 3306, // 默认 3306 database: "mydb".into(), username: "root".into(), password: "secret".into(), charset: "utf8mb4".into(), // 默认 prefix: "app_".into(), // 表前缀,P("user") → `app_user` }) .await?; set_prefix("app_"); // 单独改前缀(测试常用) set_debug(true); // 全局打印 SQL // set_pool(pool); // 注入已有 sqlx::MySqlPool // get_pool(); // 取全局连接池 ``` --- ## 入口:`P` / `D` / `P0` / `D0` | 函数 | 含义 | |------|------| | `P("user")` | 预处理语句 + 表名 | | `D("user")` | 直接拼接 SQL(不预处理) | | `P0()` | 预处理、无表(原生 SQL) | | `D0()` | 非预处理、无表 | ```rust P("user").field("id").condition(("id", 1)).find::().await?; P0().fetch::("SELECT * FROM app_user WHERE id = ?", &[1.into()]).await?; ``` --- ## 过程宏 `sql!`(推荐) 支持表达式与语句块: ```rust let n = sql!(P("user").where(["id" => 1]).delete().await?); sql! { let n = P("user") .where(["id" => 100101]) .orWhere("id", 100102) .update(["nickname" : "olnho123"]) .await?; } ``` `sql!` 会改写 PHP 风格方法名与糖语法,再交给真正的 `Db` API。 ### 方法别名 | `sql!` 内写法 | 展开为 | |---------------|--------| | `.where` / `.Where` / `.Condition` | `.condition` | | `.orWhere` / `.OrWhere` / `.orCondition` | `.or_condition` | | `.whereIn` / `.conditionIn` | `.condition_in` | | `.orWhereIn` | `.or_condition_in` | | `.whereNotIn` / `.orWhereNotIn` | `.condition_not_in` / `.or_condition_not_in` | | `.whereNull` / `.whereNotNull`(及 or 变体) | `.condition_null` / … | | `.whereBetween` / `.orWhereBetween` | `.condition_between` / … | ### `.where` / `.orWhere` 条件写法 **推荐 / 支持:** ```rust sql!(P("user").where(["id", 1])); sql!(P("user").where(["id" => 1])); sql!(P("user").where(["id": 1])); sql!(P("user").where(["id", ">", 1])); sql!(P("user").where("id", 1)); // 字段, 值 sql!(P("user").where("id", ">", 1)); // 字段, 操作符, 值 sql!(P("user").where(1)); // 裸主键 → id = sql!(P("user").where([["id", 1], ["status", 0]])); // 多条件 AND sql!(P("user").where(|q| { // 闭包分组 q.where(["pt", 0]).orWhere(["pt", 1]) })); ``` **不支持(会 `compile_error`):** ```rust sql!(P("user").where(("id", 1))); // () 元组 sql!(P("user").where(("id", 1), ("status", 0))); ``` ### IN / NULL / BETWEEN ```rust sql!( P("user") .whereIn("pt", [0, 1]) .orWhereIn("status", [2, 3]) .whereNotIn("role", [9]) .orWhereNotIn("type", [8]) .whereNull("deletedAt") .orWhereNull("bannedAt") .whereNotNull("email") .orWhereNotNull("phone") .whereBetween("id", 1, 100) // field, low, high .orWhereBetween("age", [18, 60]) // field, [low, high] .gets() .await? ); ``` `BETWEEN` 范围只接受 **`[low, high]`**,不接受 `(low, high)`。 ### 查询 / 删除糖 空参保持原样;有参时先加条件再调用方法: ```rust sql!(P("user").find(1).await?); // ≡ .where(["id": 1]).find() sql!(P("user").find(["id" => 1]).await?); sql!(P("user").delete(1).await?); sql!(P("user").delete(["id" => 1]).await?); sql!(P("user").delete("status", 0).await?); sql!(P("user").json(1).await?); // 还有 jsons / gets;fetch → find sql!(P("user").find().await?); // 无参不改写 ``` ### 更新 / 插入糖(→ `V!`) ```rust sql!(P("user").where(1).update(["nickname" : "olnho"]).await?); sql!(P("user").where(["id" => 1]).update("status", 1).await?); sql!(P("user").insert(["nickname" => "测试", "status" => 0]).await?); sql!(P("user").insert("status", 0).await?); ``` ### 完整示例 ```rust sql! { // 查一条 let row: Option = P("user").where(["id" => 1]).find().await?; // 列表 let rows = P("user") .where(["status", 1]) .whereIn("pt", [0, 1]) .order("id desc") .limit(20) .gets() .await?; // 更新 let n = P("user") .where(["id" => 100101]) .orWhere("id", 100102) .update(["nickname" : "olnho123"]) .await?; // 删除 let n = P("user").delete(["id" => 1]).await?; } ``` --- ## 声明宏 `Where!` 用于 `.condition(...)` / `.or_condition(...)`(`sql!` 外也可直接用)。 ### 调用形式 | 写法 | 是否支持 | |------|----------| | `Where!(["id": 1])` | ✅ | | `Where!(["id" => 1])` | ✅ | | `Where!(["id", 1])` | ✅ | | `Where!("id", 1)` | ✅ | | `Where!("id", ">", 1)` | ✅ | | `Where!(1)` 主键 | ✅ | | `Where!(\|q\| …)` 闭包 | ✅ | | `Where!["id": 1]` | ❌ 方括号调用 | | `Where!("id": 1)` | ❌ 无 `[]` 的 map | | `Where!(("id", 1))` | ❌ 外层元组 | ### 示例 ```rust P("user").condition(Where!(1)).gets().await?; P("user").condition(Where!(["status", 0])).gets().await?; P("user").condition(Where!(["id": 1])).delete().await?; P("user").condition(Where!("id", 1)).delete().await?; P("user").condition(Where!("id", ">=", 4)).gets().await?; // 多条件(嵌套 [],不要用元组列表) P("user") .condition(Where!([["id", 1], ["status", 0]])) .gets() .await?; P("user") .condition(Where!([["status", 0], ["id", ">", 1]])) .gets() .await?; // IS / IN / BETWEEN(操作符大小写不敏感) P("user") .condition(Where!([ ["deletedAt", "IS", "NULL"], ["email", "IS", "NOT NULL"], ["status", "IN", [0, 1, 2]], ["role", "NOT IN", [3, 4]], ["age", "BETWEEN", [18, 60]], // 不要 (18, 60) // 也支持四元:["age", "BETWEEN", 18, 60] ])) .gets() .await?; // 闭包分组(体内可再走 sql! 改写) P("user") .condition(("status", 1)) .condition(Where!(|q| q.or_condition(["pt", 0]).or_condition(["pt", 1]))) .gets() .await?; ``` > `sql!` 外仍可用 Rust 合法元组:`.condition(("id", 1))` / `.condition(("id", ">", 1))`。 --- ## 声明宏 `V!` / `data!` / `Update!` ### `V!` — insert 字段 map(兼 AppValue 构造) 对象字面量用花括号;顶层返回 `HashValue`,可直接传给 `insert`,也可作为 `one`/`all` 的行类型: ```rust P("user") .insert(V!({ "nickname": "测试用户", "status": 0 })) .await?; ``` 在 `sql!` 里通常不直接写 `V!`,而用方括号糖(内部改写为 `V!({…})`,`=>` 会转成 `:`): ```rust sql!(P("user").insert(["nickname" => "x", "status" => 0]).await?); ``` ### `data!` — update 字段 map(支持 `raw`) `update` 专用;普通值绑定为 `?`,`raw(...)` 原样写入 SET: ```rust P("user") .condition(("id", 1)) .update(data!({ "money": raw("money + 100"), "status": 1, })) .await?; ``` `sql!` 内 `update([...])` 展开为 `data!({…})`(`insert([...])` 仍是 `V!`): ```rust sql!(P("user").where(1).update(["money" => raw("money * 10")]).await?); sql!(P("user").where(1).update(["nickname" : "x"]).await?); ``` 仅绑定值时也可继续传 `V!({…})` 给 `update`。 ### `Update!` — 改内存中的 `RowMap`(不写库) ```rust let mut row: RowMap = P("user").where(1).find().await?.unwrap(); Update!(row, "image", "https://www.example.com"); Update!(row, "status": 1, "title" => "hello"); ``` --- ## `Db` 链式 API(`sql!` 外) ### 构建 ```rust P("user") .field("id,nickname,name") // 或 .select(...);也可用 field!(db, "id", "name") .condition(("status", 1)) .or_condition(("pt", 0)) .condition_in("id", [1, 2, 3]) .condition_null("deletedAt") .condition_between("age", 18, 60) .order("id desc") // 或 order!(db, "id desc") .group_by("status") .limit(10) .offset(20) .page(2, 10) // page, per_page → limit/offset .prefix("app_") // 覆盖实例前缀 .debug(true); ``` ### 查询 返回类型由 `T: sqlx::FromRow` 决定(须类型标注或由上下文推断): ```rust #[derive(sqlx::FromRow)] struct User { id: i64, nickname: String } let u: Option = P("user").condition(("id", 1)).one().await?; let list: Vec = P("user").all().await?; let row: Option = P("user").condition(("id", 1)).find().await?; let rows: Vec = P("user").gets().await?; // 与 V!/insert/update 同一类型: let hv: Option = D("user").one().await?; let hv: HashValue = row.unwrap().into(); // RowMap → HashValue let js = P("user").json().await?; // 单行 JSON(内部用 RowMap) let js = P("user").jsons().await?; // 多行 JSON let v: Option = P("user").value("nickname").await?; // 须标注 T let n = P("user").count("*").await?; // COUNT(*) let n = P("user").count("id").await?; let s: Option = P("user").sum("score").await?; // 须标注 T let mx: Option = P("user").max("id").await?; let mn: Option = P("user").min("id").await?; let av: Option = P("user").avg("score").await?; ``` `sum` / `max` / `min` / `avg` 空集时返回 `None`;`count("*")` 表示 `COUNT(*)`。 ### 写入 ```rust P("user").insert(V!({ "nickname": "a", "status": 0 })).await?; // 返回 last_insert_id 等 u64 P("user").condition(("id", 1)).update(V!({ "status": 1 })).await?; P("user").condition(("id", 1)).delete().await?; P("user").condition(("id", 1)).increment("score", 1).await?; P("user").truncate().await?; ``` `offset` 仅用于 SELECT;带 `offset` 的 `delete` / `update` 会报错。 ### JOIN **`sql!` 内三参数简写**(默认 `=`,展开为 `left_join_on` / `inner_join_on`): ```rust sql! { let row: Option = P("user as u") .field("u.id,u.name,u.age,i.mobile_phone") .left_join("info as i", "u.id", "i.id") // 或带操作符:.left_join("info as i", "u.id", "=", "i.id") .where(["u.id" => 1]) .find() .await?; } ``` 闭包 / 底层 API: ```rust let _: Vec = P("user") .left_join("comment", |join| { on!(join, [("user.id", "=", "comment.uid")]); // on!(join, or [("user.id", "=", "comment.tuid")]); }) .gets() .await?; P("user").left_join_on("comment", "user.id", "=", "comment.uid"); P("user").inner_join_on("profile", "user.id", "=", "profile.uid"); ``` `on!` 示例: ```rust on!(join, [("u.id", "=", "c.uid"), ("c.tuid", "=", 100)]); on!(join, or [("u.id", "=", "c.tuid"), ("c.uid", "=", 100)]); on!(join, ("u.id", "=", "c.uid")); ``` --- ## 原生 SQL 宏 ```rust // 第一条;无绑定走 D0,有绑定走 P0 let row = one!("SELECT * FROM app_user WHERE id = ?", 1)?; let row = fetch_one!("SELECT * FROM app_user WHERE id = ?", 1)?; let row = query_one!("SELECT * FROM app_user WHERE id = ?", 1)?; // 全部 let rows = all!("SELECT * FROM app_user WHERE status = ?", 1)?; let rows = fetch_all!(...)?; let rows = query_all!(...)?; // 执行写 let n = execute!("UPDATE app_user SET status = ? WHERE id = ?", 1, 100)?; ``` 也可用: ```rust P0().fetch::(sql, &bindings).await?; P0().query::(sql, &bindings).await?; P0().execute(sql, &bindings).await?; ``` --- ## `field!` / `order!` / `or_condition!` ```rust let db = field!(P("user"), "id", "nickname"); // 含函数/表达式时自动不加反引号,无需 raw: let db = P("user").field("COUNT(*) as cnt, SUM(score) as total"); // 仍可用 raw / => raw 强制原样: let db = field!(db, "IF(status=1,1,0)" => raw); let db = order!(db, "id desc", "created_at asc"); // 命令式追加 OR 组(挂到 AND 下) let db = or_condition!(P("user"), [["pt", "=", 0], ["pt", "=", 1]]); let db = orCondition!(db, "id", 1); // 别名 let db = or_condition!(db, { "pt" => 0, "status" => 1 }); // 不要:.condition(or_condition!([...])) → compile_error // 请用闭包: P("user").condition(|q| q.or_condition(("pt", 0)).or_condition(("pt", 1))); ``` --- ## 事务 `transaction!` ### 自动作用域(推荐) 进入块 `BEGIN`;`Ok(())` → `COMMIT`;任意 `?` → `ROLLBACK`。 ```rust transaction!({ P("user") .condition(Where!(["id": 1])) .update(V!({ "status": 1 })) .await?; sql! { let _ = P("slider").where(2).update(["url" : ""]).await?; } Ok(()) // 块末尾必须 Ok(()) })?; ``` 块内 `find` / `gets` / `json` / `insert` / `update` / `delete` 等会自动走同一事务连接。 ### 手动传入 `tx` ```rust transaction!(tx, { P("user") .condition(Where!(["id": 1])) .update_in(tx.as_executor(), V!({ "status": 1 })) .await?; Ok(()) })?; ``` ### 完全手写 ```rust let mut tx = rust_orm::begin_transaction().await?; P("user") .condition(Where!(["id": 1])) .update_in(tx.as_executor(), V!({ "status": 1 })) .await?; tx.commit().await?; // 出错时自行 tx.rollback().await? ``` ### 注意 1. 块末尾必须 `Ok(())`,闭包类型为 `Result<()>`。 2. 不要在事务块内 `spawn` 子任务再访问库(连接在 task-local)。 3. `sql!` 内的写操作同样会走当前事务。 --- ## 语法对照速查 | 场景 | ✅ 推荐 | ❌ 避免 | |------|---------|---------| | `sql!` 单条件 | `.where(["id" => 1])` / `.where("id", 1)` / `.where(1)` | `.where(("id", 1))` | | `sql!` 多条件 | `.where([["id", 1], ["status", 0]])` | `.where([("id", 1), ("status", 0)])` | | `Where!` 调用 | `Where!(["id": 1])` / `Where!("id", 1)` | `Where!["id": 1]` / `Where!("id": 1)` | | BETWEEN | `["age", "BETWEEN", [18, 60]]` | `["age", "BETWEEN", (18, 60)]` | | 更新 SET | `sql!(….update(["name": "x"]))` → `data!`;或 `data!({…})` / `V!({…})` | — | --- ## 其他导出 - 错误:`DbError`、`Result` - 行类型:`RowMap` / `HashValue`(均实现 `sqlx::FromRow`,可互转;`IntoWriteMap` / `IntoCondition`);`one`/`all`/`query`/`fetch` 泛型须标注 `T`;`ToJson` / `ToJsons` - 值:`AppValue`、`RawExpr`、`raw(...)`、`SelectField` - DDL 辅助:`table` / `tables` / `table_exists` / `table_fields` / `truncate_table` / `rename_table` / `delete_table` / `download_table` / `field_add` / `field_update` / `field_delete` / `field_exists` --- ## 许可与风格 API 设计对标 PHP `PdoDb.php` 的链式习惯;在 Rust 中优先使用过程宏 `sql!` 获得 `where` / `orWhere` / `find(1)` 等糖语法,复杂条件可用 `Where!` + `.condition`。