在 Rust 中使用rbatis查询表主要有三种方式:自动 CRUD、Wrapper 条件查询、以及自定义 SQL(htmlsql/pysql)。以下是完整的实用指南:
1. 添加依赖
toml
[dependencies] rbatis = "4.5" # 或当前最新版本 rbdc-sqlite = "4.5" # 根据你的数据库选择:rbdc-mysql, rbdc-pg, rbdc-mssql serde = { version = "1", features = ["derive"] } tokio = { version = "1", features = ["full"] }2. 定义实体
使用crud_table宏自动映射表结构:
rust
use rbatis::crud::CRUDTable; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize, CRUDTable)] #[table_name = "user"] // 指定表名 pub struct User { pub id: Option<i64>, pub name: Option<String>, pub age: Option<i32>, pub email: Option<String>, }3. 初始化 RBatis
rust
use rbatis::rbatis::Rbatis; use rbdc_sqlite::driver::SqliteDriver; lazy_static::lazy_static! { static ref RB: Rbatis = Rbatis::new(); } #[tokio::main] async fn main() { // 初始化连接池(以 SQLite 为例) RB.init(SqliteDriver {}, "sqlite://target/test.db").unwrap(); // 执行查询... }4. 查询方式
方式一:全表查询(自动 CRUD)
rust
// 查询所有用户 let users: Vec<User> = RB.fetch_list().await.unwrap(); println!("{:?}", users);方式二:条件查询(Wrapper)
rust
use rbatis::wrapper::Wrapper; // 构建查询条件 let w = RB.new_wrapper() .eq("age", 18) // age = 18 .like("name", "%张三%") // name LIKE '%张三%' .order_by(true, &["id"]); // ORDER BY id ASC let users: Vec<User> = RB.fetch_list_by_wrapper(&w).await.unwrap();Wrapper 常用方法:
表格
| 方法 | 说明 |
|---|---|
.eq("col", val) | 等于 |
.ne("col", val) | 不等于 |
.gt("col", val)/.ge("col", val) | 大于 / 大于等于 |
.lt("col", val)/.le("col", val) | 小于 / 小于等于 |
.like("col", "%val%") | 模糊查询 |
.in_array("col", &vec![1,2,3]) | IN 查询 |
.is_null("col")/.is_not_null("col") | NULL 判断 |
.and()/.or() | 逻辑连接 |
.order_by(asc, &["col"]) | 排序 |
方式三:根据主键查询
rust
let user: Option<User> = RB.fetch_by_id::<User>(&1i64).await.unwrap();方式四:自定义 SQL(推荐复杂查询)
使用htmlsql宏(类似 MyBatis 的 XML):
rust
use rbatis::{htmlsql, crud::CRUDTable}; #[htmlsql(" <select> SELECT * FROM user <where> <if test='name != \"\"'> AND name LIKE #{name} </if> <if test='age != 0'> AND age > #{age} </if> </where> </select> ")] async fn select_by_condition(rb: &Rbatis, name: &str, age: i32) -> Vec<User> { impled!() } // 调用 let users = select_by_condition(&RB, "%张三%", 18).await;或使用pysql宏(Python 风格模板):
rust
use rbatis::pysql; #[pysql(" SELECT * FROM user WHERE 1=1 ${if name != '': 'AND name LIKE #{name}'} ${if age > 0: 'AND age > #{age}'} ")] async fn select_by_condition(rb: &Rbatis, name: &str, age: i32) -> Vec<User> { impled!() }方式五:执行原生 SQL
rust
let sql = "SELECT * FROM user WHERE age > ?"; let users: Vec<User> = RB.fetch_prepare("", sql, vec![rbatis::Value::I32(18)]) .await .unwrap();5. 分页查询
rust
use rbatis::plugin::page::{Page, PageRequest}; let req = PageRequest::new(1, 10); // 第1页,每页10条 let w = RB.new_wrapper().eq("status", 1); let page: Page<User> = RB.fetch_page_by_wrapper(&w, &req).await.unwrap(); println!("总条数: {}", page.total); println!("数据: {:?}", page.records);6. 完整示例
rust
use rbatis::rbatis::Rbatis; use rbatis::crud::CRUDTable; use rbatis::wrapper::Wrapper; use serde::{Deserialize, Serialize}; use rbdc_sqlite::driver::SqliteDriver; #[derive(Clone, Debug, Serialize, Deserialize, CRUDTable)] #[table_name = "user"] struct User { pub id: Option<i64>, pub name: Option<String>, pub age: Option<i32>, } lazy_static::lazy_static! { static ref RB: Rbatis = Rbatis::new(); } #[tokio::main] async fn main() { RB.init(SqliteDriver {}, "sqlite://test.db").unwrap(); // 1. 查全部 let all: Vec<User> = RB.fetch_list().await.unwrap(); // 2. 条件查询 let w = RB.new_wrapper() .ge("age", 18) .like("name", "%李%"); let list: Vec<User> = RB.fetch_list_by_wrapper(&w).await.unwrap(); // 3. 查单个 let one: Option<User> = RB.fetch_by_id(&1i64).await.unwrap(); println!("查询结果: {:?}, {:?}, {:?}", all, list, one); }关键提示
字段映射:默认下划线转驼峰(
user_name↔user_name),如需自定义用#[column_name = "user_name"]日志:开启
log或tracing可看到实际执行的 SQL连接池:
RB.init()内部已集成连接池,无需额外配置事务:使用
RB.begin_tx()/RB.commit()/RB.rollback()
如果你用的是rbatis 3.x或2.x,API 略有不同(主要是CRUDTable改为CRUD等),建议优先使用4.x版本。需要针对特定数据库(MySQL/PostgreSQL)的示例吗?