WebSite | Showcase

Build Status doc.rs unsafe forbidden GitHub release discussions

A async, pure Rust SQL Toolkit,compile-time Dynamic SQL,Compile Time ORM.

It is an ORM, a small compiler, a dynamic SQL languages

Thanks to SQLX, deadpool, Tiberius, MyBatis,xorm and so on reference design or code implementation. release of V4.0 is Inspired and supported by these frameworks

Performance

//---- bench_insert stdout ----(macos,cpu-M1Max) //use Time: 102.610583ms ,each:1026 ns/op //use QPS: 974529 QPS/s

Supported data structures

| data structure | is supported | |---------------------------------------------------------------------------|--------------| | Option | √ | | Vec | √ |
| HashMap | √ | | i32,i64,f32,f64,bool,String...more rust type | √ |
| rbatis::rbdc::types::{Date,FastDateTime,Time,Timestamp,Decimal,Json} | √ | | rbatis::plugin::page::{Page, PageRequest} | √ | | rbs::Value* | √ | | serde_json::* | √ | | any serde type | √ | | driver type on package (rdbc-mysql/types,rbdc-pg/types,rbdc-sqlite/types) | √ |

Supported database driver

| database | crates.io | github_link | |---------------|-----------------------------------------------------|-------------------------------------------------------------| | Mysql | rbdc-mysql | rbatis | | Postgres | rbdc-pg | rbatis | | Sqlite | rbdc-sqlite | rbatis | | Mssql | rbdc-mssql | rbatis | | MariaDB | rbdc-mysql | rbatis | | TiDB | rbdc-mysql | rbatis | | CockroachDB | rbdc-pg | rbatis | | Oracle | rbdc-oracle | chenpengfan |

Supported OS/Platforms by Workflows CI

| platform | is supported | |-------------------------|--------------| | Linux(unbutu laster*) | √ | | Apple/MacOS(laster) | √ |
| Windows(latest) | √ |

Supported Web Frameworks

Quick example: QueryWrapper and common usages (see example/crud_test.rs for details)

```toml tokio = { version = "1", features = ["full"] } log = "0.4" fast_log = "1.5" serde = { version = "1", features = ["derive"] } rbs = { version = "0.1"} rbatis = { version = "4.0"} rbdc-sqlite = { version = "0.1" }

rbdc-mysql={version="0.1"}

rbdc-pg={version="0.1"}

rbdc-mssql={version="0.1"}

...and more driver

```

```rust //#[macro_use] define in 'root crate' or 'mod.rs' or 'main.rs'

[macro_use]

extern crate rbatis; extern crate rbdc; use rbatis::rbdc::datetime::FastDateTime;

[derive(Clone, Debug, Serialize, Deserialize)]

pub struct BizActivity { pub id: Option, pub name: Option, pub pclink: Option, pub h5link: Option, pub pcbannerimg: Option, pub h5bannerimg: Option, pub sort: Option, pub status: Option, pub remark: Option, pub createtime: Option, pub version: Option, pub deleteflag: Option, } crud!(BizActivity{});//crud = insert+selectbycolumn+updatebycolumn+deletebycolumn

implselect!(BizActivity{selectallbyid(id:&str,name:&str) => "where id = #{id} and name = #{name}"}); implselect!(BizActivity{selectbyid(id:String) -> Option => "where id = #{id} limit 1"}); implupdate!(BizActivity{updatebyname(name:&str) => "where id = 1"}); impldelete!(BizActivity {deletebyname(name:&str) => "where name= '2'"}); implselectpage!(BizActivity{selectpage(name:&str) => "where name != #{name}"});

[tokio::main]

async fn main() { /// enable log crate to show sql logs fastlog::init(fastlog::Config::new().console()).expect("rbatis init fail"); /// initialize rbatis. also you can call rb.clone(). this is an Arc point let rb = Rbatis::new(); /// connect to database
// sqlite rb.init(SqliteDriver {}, "sqlite://target/sqlite.db").unwrap(); // mysql // rb.init(MysqlDriver{},"mysql://root:123456@localhost:3306/test").unwrap(); // postgresql // rb.init(PgDriver{},"postgres://postgres:123456@localhost:5432/postgres").unwrap(); // mssql/sqlserver // rb.init(MssqlDriver{},"jdbc:sqlserver://localhost:1433;User=SA;Password={TestPass!123456};Database=test").unwrap();

let activity = BizActivity {
    id: Some("2".into()),
    name: Some("2".into()),
    pc_link: Some("2".into()),
    h5_link: Some("2".into()),
    pc_banner_img: None,
    h5_banner_img: None,
    sort: None,
    status: Some(2),
    remark: Some("2".into()),
    create_time: Some(FastDateTime::now()),
    version: Some(1),
    delete_flag: Some(1),
};
let data = BizActivity::insert(&mut rb, &activity).await;
println!("insert = {:?}", data);

let data = BizActivity::select_all_by_id(&mut rb, "1", "1").await;
println!("select_all_by_id = {:?}", data);

let data = BizActivity::select_by_id(&mut rb, "1".to_string()).await;
println!("select_by_id = {:?}", data);

let data = BizActivity::update_by_column(&mut rb, &activity, "id").await;
println!("update_by_column = {:?}", data);

let data = BizActivity::update_by_name(&mut rb, &activity, "test").await;
println!("update_by_name = {:?}", data);

let data = BizActivity::delete_by_column(&mut rb, "id", &"2".into()).await;
println!("delete_by_column = {:?}", data);

let data = BizActivity::delete_by_name(&mut rb, "2").await;
println!("delete_by_column = {:?}", data);

let data = BizActivity::select_page(&mut rb, &PageRequest::new(1, 10), "2").await;
println!("select_page = {:?}", data);

} ///...more usage,see crud.rs ```

pub async fn main() { use rbatis::Rbatis; use rbdcsqlite::driver::SqliteDriver; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct BizActivity { pub id: Option, pub name: Option, } fastlog::init(fastlog::Config::new().console()).expect("rbatis init fail"); let rb = Rbatis::new(); rb.init(SqliteDriver {}, "sqlite://target/sqlite.db").unwrap(); let table: Option = rb .fetchdecode("select * from bizactivity limit ?", vec![rbs::tovalue!(1)]) .await .unwrap(); let count: u64 = rb .fetchdecode("select count(1) as count from bizactivity", vec![]) .await .unwrap(); println!(">>>>> table={:?}", table); println!(">>>>> count={}", count); } ```

macros

Because of the compile time, the annotations need to declare the database type to be used.

rust #[py_sql("select * from biz_activity where delete_flag = 0 if name != '': `and name=#{name}`")] async fn py_sql_tx(rb: &Rbatis, tx_id: &String, name: &str) -> Vec<BizActivity> { impled!() }

Because of the compile time, the annotations need to declare the database type to be used

html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://raw.githubusercontent.com/rbatis/rbatis/master/rbatis-codegen/mybatis-3-mapper.dtd"> <mapper> <select id="select_by_condition"> `select * from biz_activity where ` <if test="name != ''"> name like #{name} </if> </select> </mapper>

```rust ///select page must have '?:&PageRequest' arg and return 'Page'

[html_sql("example/example.html")]

async fn selectbycondition(rb: &mut dyn Executor, page_req: &PageRequest, name: &str) -> Page { impled!() } ```

```rust use once_cell::sync::Lazy;

pub static RB: Lazy = Lazy::new(|| Rbatis::new());

/// Macro generates execution logic based on method definition, similar to @select dynamic SQL of Java/Mybatis /// RB is the name referenced locally by Rbatis, for example DAO ::RB, com:: XXX ::RB... Can be /// The second parameter is the standard driver SQL. Note that the corresponding database parameter mysql is? , pg is $1... /// macro auto edit method to 'pub async fn select(name: &str) -> rbatis::core::Result {}' ///

[sql("select * from biz_activity where id = ?")]

pub async fn select(rb: &Rbatis, name: &str) -> BizActivity {} //or: pub async fn select(name: &str) -> rbatis::core::Result {}

[tokio::test]

pub async fn testmacro() { fastlog::init(fast_log::Config::new().console()).expect("rbatis init fail"); RB.link("mysql://root:123456@localhost:3306/test").await.unwrap(); let a = select(&RB, "1").await.unwrap(); println!("{:?}", a); } ```

Changelog

Roadmap

Contact/donation, or click on star rbatis

联系方式/捐赠,或 rbatis 点star

捐赠

zxj347284221

联系方式(添加好友请备注'rbatis') 微信群:先加微信,然后拉进群

zxj347284221