#orm #sqlite #mysql #postgresql

rbatis

The Rust SQL Toolkit and ORM Library. An async, pure Rust SQL crate featuring compile-time Dynamic SQL

174 stable releases

new 4.5.51 Apr 29, 2025
4.5.50 Feb 3, 2025
4.5.49 Jan 12, 2025
4.5.48 Dec 20, 2024
1.0.7 Feb 29, 2020

#43 in Database interfaces

Download history 921/week @ 2025-01-07 610/week @ 2025-01-14 502/week @ 2025-01-21 326/week @ 2025-01-28 726/week @ 2025-02-04 786/week @ 2025-02-11 329/week @ 2025-02-18 481/week @ 2025-02-25 269/week @ 2025-03-04 555/week @ 2025-03-11 386/week @ 2025-03-18 341/week @ 2025-03-25 261/week @ 2025-04-01 322/week @ 2025-04-08 361/week @ 2025-04-15 533/week @ 2025-04-22

1,531 downloads per month
Used in 33 crates (25 directly)

Apache-2.0

780KB
13K SLoC

Rbatis

Website | Showcase | Examples

Build Status doc.rs unsafe forbidden codecov GitHub release discussions

Introduction

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.

Core Advantages

1. High Performance

  • Compile-time Dynamic SQL Generation: Converts SQL statements to Rust code during compilation, avoiding runtime overhead
  • Based on Tokio Async Model: Fully utilizes Rust's async features to enhance concurrency performance
  • Efficient Connection Pools: Built-in multiple connection pool implementations, optimizing database connection management

2. Reliability

  • Rust Safety Features: Leverages Rust's ownership and borrowing checks to ensure memory and thread safety
  • Unified Parameter Placeholders: Uses ? as a unified placeholder, supporting all drivers
  • Two Replacement Modes: Precompiled #{arg} and direct replacement ${arg}, meeting different scenario requirements

3. Development Efficiency

4. Extensibility

  • Multiple Database Support: MySQL, PostgreSQL, SQLite, MSSQL, MariaDB, TiDB, CockroachDB, Oracle, TDengine, etc.
  • Custom Driver Interface: Implement a simple interface to add support for new databases
  • Multiple Connection Pools: FastPool (default), Deadpool, MobcPool
  • Compatible with Various Web Frameworks: Seamlessly integrates with ntex, actix-web, axum, hyper, rocket, tide, warp, salvo, and more

Supported Database Drivers

Database (crates.io) GitHub Link
MySQL rbatis/rbdc-mysql
PostgreSQL rbatis/rbdc-pg
SQLite rbatis/rbdc-sqlite
MSSQL rbatis/rbdc-mssql
MariaDB rbatis/rbdc-mysql
TiDB rbatis/rbdc-mysql
CockroachDB rbatis/rbdc-pg
Oracle chenpengfan/rbdc-oracle
TDengine tdcare/rbdc-tdengine

Supported Connection Pools

Connection Pool (crates.io) GitHub Link
FastPool (default) rbatis/fast_pool
Deadpool rbatis/rbdc-pool-deadpool
MobcPool rbatis/rbdc-pool-mobc

Supported Data Types

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

How Rbatis Works

Rbatis uses compile-time code generation through the rbatis-codegen crate, which means:

  1. Zero Runtime Overhead: Dynamic SQL is converted to Rust code during compilation, not at runtime. This provides performance similar to handwritten code.

  2. Compilation Process:

    • Lexical Analysis: Handled by func.rs in rbatis-codegen using Rust's syn and quote crates
    • Syntax Parsing: Performed by parser_html and parser_pysql modules in rbatis-codegen
    • Abstract Syntax Tree: Built using structures defined in the syntax_tree package in rbatis-codegen
    • Intermediate Code Generation: Executed by func.rs, which contains all the code generation functions
  3. Build 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.

  4. 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.

Performance Benchmarks

---- 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

Quick Start

Dependencies

# Cargo.toml
[dependencies]
rbs = { version = "4.5"}
rbatis = { version = "4.5"}
rbdc-sqlite = { version = "4.5" }
# Or other database drivers
# rbdc-mysql = { version = "4.5" }
# rbdc-pg = { version = "4.5" }
# rbdc-mssql = { version = "4.5" }

# Other dependencies
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
log = "0.4"
fast_log = "1.6"

Basic Usage

use rbatis::rbdc::datetime::DateTime;
use rbatis::crud::{CRUD, CRUDTable};
use rbatis::rbatis::RBatis;
use rbdc_sqlite::driver::SqliteDriver;
use serde::{Deserialize, Serialize};

#[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{});

// Custom SQL methods
impl_select!(BizActivity{select_by_id(id:String) -> Option => "`where id = #{id} limit 1`"});
impl_select_page!(BizActivity{select_page(name:&str) => "`where name != #{name}`"});

#[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 result = BizActivity::insert(&rb, &activity).await;
    println!("Insert result: {:?}", result);

    // Query data
    let data = BizActivity::select_by_id(&rb, "1".to_string()).await;
    println!("Query result: {:?}", data);
    
    // Pagination query
    use rbatis::plugin::page::PageRequest;
    let page_data = BizActivity::select_page(&rb, &PageRequest::new(1, 10), "").await;
    println!("Page result: {:?}", page_data);
}

Creating a Custom Database Driver

To implement a custom database driver for Rbatis:

  1. Define your driver project with dependencies:
[features]
default = ["tls-rustls"]
tls-rustls=["rbdc/tls-rustls"]
tls-native-tls=["rbdc/tls-native-tls"]
[dependencies]
rbs = { version = "4.5"}
rbdc = { version = "4.5", default-features = false, optional = true }
fastdate = { version = "0.3" }
tokio = { version = "1", features = ["full"] }
  1. Implement the required traits:
// Implement the following traits from rbdc
use rbdc::db::{ConnectOptions, Connection, ExecResult, MetaData, Placeholder, Row};

// Implementation details for your database driver...
struct YourDatabaseDriver;

// Example implementation (simplified)
impl ConnectOptions for YourDatabaseDriver {
    // Implementation details
}

impl Connection for YourDatabaseDriver {
    // Implementation details
}

// Implement other required traits

// Then use your driver:
#[tokio::main]
async fn main() {
  let rb = rbatis::RBatis::new();
  rb.init(YourDatabaseDriver {}, "yourdatabase://username:password@host:port/dbname").unwrap();
}

More Information

Contact Us

discussions

Donations or Contact

zxj347284221

WeChat (Please note 'rbatis' when adding as friend)

zxj347284221

Dependencies

~12–22MB
~313K SLoC