| Crates.io | rbatis |
| lib.rs | rbatis |
| version | 4.6.8 |
| created_at | 2020-02-15 14:08:36.83469+00 |
| updated_at | 2025-07-02 10:42:21.721615+00 |
| description | The Rust SQL Toolkit and ORM Library. An async, pure Rust SQL crate featuring compile-time Dynamic SQL |
| homepage | https://rbatis.github.io/rbatis.io |
| repository | https://github.com/rbatis/rbatis |
| max_upload_size | |
| id | 209474 |
| size | 688,659 |
Rbatis is a high-performance ORM framework for Rust based on compile-time code generation. It perfectly balances development efficiency, performance, and stability, functioning as both an ORM and a dynamic SQL compiler.
? as a unified placeholder, supporting all drivers#{arg} and direct replacement ${arg}, meeting different scenario requirementsif, for, choose/when/otherwise, bind, trim structures and collection operations (.sql(), .csv())<if>, <where>, <set>, <foreach>), declarative SQL building, and automatic handling of SQL fragments without requiring CDATA| Connection Pool (crates.io) | GitHub Link |
|---|---|
| FastPool (default) | rbatis/fast_pool |
| Deadpool | rbatis/rbdc-pool-deadpool |
| MobcPool | rbatis/rbdc-pool-mobc |
| Data Type | Support |
|---|---|
Option |
✓ |
Vec |
✓ |
HashMap |
✓ |
i32, i64, f32, f64, bool, String, and other Rust base types |
✓ |
rbatis::rbdc::types::{Bytes, Date, DateTime, Time, Timestamp, Decimal, Json} |
✓ |
rbatis::plugin::page::{Page, PageRequest} |
✓ |
rbs::Value |
✓ |
serde_json::Value and other serde types |
✓ |
| Driver-specific types from rbdc-mysql, rbdc-pg, rbdc-sqlite, rbdc-mssql | ✓ |
| crate | GitHub Link |
|---|---|
| rbdc | rbdc |
| rbs | rbs |
Rbatis uses compile-time code generation through the rbatis-codegen crate, which means:
Zero Runtime Overhead: Dynamic SQL is converted to Rust code during compilation, not at runtime. This provides performance similar to handwritten code.
Compilation Process:
func.rs in rbatis-codegen using Rust's syn and quote cratesparser_html and parser_pysql modules in rbatis-codegensyntax_tree package in rbatis-codegenfunc.rs, which contains all the code generation functionsBuild Process Integration: The entire process runs during the cargo build phase as part of Rust's procedural macro compilation. The generated code is returned to the Rust compiler for LLVM compilation to produce machine code.
Dynamic SQL Without Runtime Cost: Unlike most ORMs that interpret dynamic SQL at runtime, Rbatis performs all this work at compile-time, resulting in efficient and type-safe code.
---- bench_raw stdout ----(windows/SingleThread)
Time: 52.4187ms ,each:524 ns/op
QPS: 1906435 QPS/s
---- bench_select stdout ----(macos-M1Cpu/SingleThread)
Time: 112.927916ms ,each:1129 ns/op
QPS: 885486 QPS/s
---- bench_insert stdout ----(macos-M1Cpu/SingleThread)
Time: 346.576666ms ,each:3465 ns/op
QPS: 288531 QPS/s
# Cargo.toml
[dependencies]
rbs = { version = "4.6"}
rbatis = { version = "4.6"}
#drivers
rbdc-sqlite = { version = "4.6" }
# rbdc-mysql = { version = "4.6" }
# rbdc-pg = { version = "4.6" }
# rbdc-mssql = { version = "4.6" }
# Other dependencies
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
log = "0.4"
fast_log = "1.6"
use rbatis::rbdc::datetime::DateTime;
use rbs::value;
use rbatis::RBatis;
use rbdc_sqlite::driver::SqliteDriver;
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BizActivity {
pub id: Option<String>,
pub name: Option<String>,
pub status: Option<i32>,
pub create_time: Option<DateTime>,
pub additional_field: Option<String>,
}
// Automatically generate CRUD methods
crud!(BizActivity{});
#[tokio::main]
async fn main() {
// Configure logging
fast_log::init(fast_log::Config::new().console()).expect("rbatis init fail");
// Initialize rbatis
let rb = RBatis::new();
// Connect to database
rb.init(SqliteDriver {}, "sqlite://target/sqlite.db").unwrap();
// Or other databases
// rb.init(MysqlDriver{}, "mysql://root:123456@localhost:3306/test").unwrap();
// rb.init(PgDriver{}, "postgres://postgres:123456@localhost:5432/postgres").unwrap();
// Create data
let activity = BizActivity {
id: Some("1".into()),
name: Some("Test Activity".into()),
status: Some(1),
create_time: Some(DateTime::now()),
additional_field: Some("Extra Information".into()),
};
// Insert data
let data = BizActivity::insert(&rb, &activity).await;
// Batch insert
let data = BizActivity::insert_batch(&rb, &vec![BizActivity {
id: Some("2".into()),
name: Some("Activity 2".into()),
status: Some(1),
create_time: Some(DateTime::now()),
additional_field: Some("Info 2".into()),
}, BizActivity {
id: Some("3".into()),
name: Some("Activity 3".into()),
status: Some(1),
create_time: Some(DateTime::now()),
additional_field: Some("Info 3".into()),
},
], 10).await;
// Update by map condition
let data = BizActivity::update_by_map(&rb, &activity, value!{ "id": "1" }).await;
// Query by map condition
let data = BizActivity::select_by_map(&rb, value!{"id":"2","name":"Activity 2"}).await;
// LIKE query
let data = BizActivity::select_by_map(&rb, value!{"name like ":"%Activity%"}).await;
// Greater than query
let data = BizActivity::select_by_map(&rb, value!{"id > ":"2"}).await;
// IN query
let data = BizActivity::select_by_map(&rb, value!{"id": &["1", "2", "3"]}).await;
// Delete by map condition
let data = BizActivity::delete_by_map(&rb, value!{"id": &["1", "2", "3"]}).await;
}
To implement a custom database driver for Rbatis:
[features]
default = ["tls-rustls"]
tls-rustls=["rbdc/tls-rustls"]
tls-native-tls=["rbdc/tls-native-tls"]
[dependencies]
rbs = { version = "4.6"}
rbdc = { version = "4.6", default-features = false, optional = true }
fastdate = { version = "0.3" }
tokio = { version = "1", features = ["full"] }
use rbdc::db::{Driver, MetaData, Row, Connection, ConnectOptions, Placeholder};
pub struct YourDriver{}
impl Driver for YourDriver{}
pub struct YourMetaData{}
impl MetaData for YourMetaData{}
pub struct YourRow{}
impl Row for YourRow{}
pub struct YourConnection{}
impl Connection for YourConnection{}
pub struct YourConnectOptions{}
impl ConnectOptions for YourConnectOptions{}
pub struct YourPlaceholder{}
impl Placeholder for YourPlaceholder{}
// Then use your driver:
#[tokio::main]
async fn main() {
let rb = rbatis::RBatis::new();
rb.init(YourDatabaseDriver {}, "database://username:password@host:port/dbname").unwrap();
}
WeChat (Please note 'rbatis' when adding as friend)