Git Product home page Git Product logo

rbatis's Introduction

WebSite | WebSite-Chinese | Showcase

Build Status doc.rs unsafe forbidden GitHub release discussions

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

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

  • No Runtimes,No Garbage Collection,High performance, Based on Future/Tokio
  • Zero cost Dynamic SQL, implemented using (proc-macro,compile-time,Cow(Reduce unnecessary cloning)) techniques。 don't need ONGL engine(mybatis)
  • JDBC-like driver design, driver use cargo.toml dependency and Box<dyn Driver> separation
  • All database drivers supported #{arg}, ${arg},? placeholder
  • Dynamic SQL(Write code freely in SQL),pagination, py_sql query lang and html_sql(Inspired Mybatis).
  • Dynamic configuration connection pool(Based on the mobc)
  • Supports logging, customizable logging based on log crate
  • 100% Safe Rust with #![forbid(unsafe_code)] enabled
  • Support use Trait System Add py_sql/ html_sql functions.see
  • rbatis/example (import into Clion!)
  • abs_admin project an complete background user management system( Vue.js+rbatis+actix-web)
  • Thanks to SQLX, mobc, Tiberius, MyBatis,xorm and so on reference design or code implementation. release of V4.0 is Inspired and supported by these frameworks

Performance

  • this bench test is MockTable,MockDriver,MockConnection to Assume that the network I/O time is 0
  • run code MockTable::insert(&mut rbatis.clone(),&t).await; on benches/fn bench_insert()
  • use command cargo test --release --package rbatis --bench raw_performance bench_insert --no-fail-fast -- --exact -Z unstable-options --show-output
//---- bench_insert stdout ----(win10,cpu-amd5950x)
// use Time: 130.5443ms ,each:1305 ns/op
// use QPS: 765860 QPS/s
//---- bench_insert stdout ----(macos,cpu-M1Max)
//use Time: 128.635666ms ,each:1286 ns/op
//use QPS: 777351 QPS/s

Supported data structures

data structure is supported
Option
Vec
HashMap
i32,i64,f32,f64,bool,String...more rust type
rbdc::types::Date
rbdc::types::FastDateTime
rbdc::types::Time
rbdc::types::Timestamp
rbdc::types::Decimal
rbdc::types::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 is supported
Mysql
Postgres
Sqlite
Mssql
Oracle x(10%)
MariaDB(=Mysql)
TiDB(=Mysql)
CockroachDB(=Postgres)

Supported OS/Platforms by Workflows CI

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

Supported Web Frameworks

  • any web Frameworks just like actix-web,axum,hyper*,rocket,tide,warp,salvo...... and more
Quick example: QueryWrapper and common usages (see example/crud_test.rs for details)
  • Cargo.toml
# add this library,and cargo install

# serde/rbs (required)
serde = { version = "1", features = ["derive"] }
rbs = "0.1"
# logging lib(required)
log = "0.4"
fast_log="1.3"
# rbatis (required)
rbatis =  { version = "4.0" }
# rbdc driver (required)
rbdc={version="0.1"}
# choose any rbdc drivier
rbdc-sqlite={version="0.1"}
#rbdc-mysql={version="0.1"}
#rbdc-pg={version="0.1"}
#rbdc-mssql={version="0.1"}
#rbdc-oracle={version="0.1"}
//#[macro_use] define in 'root crate' or 'mod.rs' or 'main.rs'
#[macro_use]
extern crate rbatis;
extern crate rbdc;
use rbatis::{impl_insert,impl_insert,impl_update,impl_delete,impl_select_page};
use rbdc::datetime::FastDateTime;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BizActivity {
  pub id: Option<String>,
  pub name: Option<String>,
  pub pc_link: Option<String>,
  pub h5_link: Option<String>,
  pub pc_banner_img: Option<String>,
  pub h5_banner_img: Option<String>,
  pub sort: Option<String>,
  pub status: Option<i32>,
  pub remark: Option<String>,
  pub create_time: Option<FastDateTime>,
  pub version: Option<i64>,
  pub delete_flag: Option<i32>,
}
crud!(BizActivity{});//crud = insert+select_by_column+update_by_column+delete_by_column

impl_select!(BizActivity{select_all_by_id(id:&str,name:&str) => "`where id = #{id} and name = #{name}`"});
impl_select!(BizActivity{select_by_id(id:String) -> Option => "`where id = #{id} limit 1`"});
impl_update!(BizActivity{update_by_name(name:&str) => "`where id = 1`"});
impl_delete!(BizActivity {delete_by_name(name:&str) => "`where name= '2'`"});
impl_select_page!(BizActivity{select_page(name:&str) => "`where name != #{name}`"});

#[tokio::main]
async fn main() {
  /// enable log crate to show sql logs
  fast_log::init(fast_log::Config::new().console());
  /// initialize rbatis. also you can call rb.clone(). this is  an Arc point
  let rb = Rbatis::new();
  /// connect to database  
  // sqlite 
  rb.link(SqliteDriver {},"sqlite://target/sqlite.db").await.unwrap();
  // mysql 
  // rb.link(MysqlDriver{},"mysql://root:123456@localhost:3306/test").await.unwrap();
  // postgresql 
  // rb.link(PgDriver{},"postgres://postgres:123456@localhost:5432/postgres").await.unwrap();
  // mssql/sqlserver
  // rb.link(MssqlDriver{},"jdbc:sqlserver://localhost:1433;User=SA;Password={TestPass!123456};Database=test").await.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

macros (new addition)

  • Important update (pysql removes runtime, directly compiles to static rust code) This means that the performance of SQL generated using py_sql,html_sql is roughly similar to that of handwritten code.

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

    #[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!() }
  • Added html_sql support, a form of organization similar to MyBatis, to facilitate migration of Java systems to Rust( Note that it is also compiled as Rust code at build time and performs close to handwritten code) this is very faster

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://github.com/rbatis/rbatis_codegen/raw/main/mybatis-3-mapper.dtd">
<mapper>
    <select id="select_by_condition">
        `select * from biz_activity where `
        <if test="name != ''">
            name like #{name}
        </if>
    </select>
</mapper>
    ///select page must have  '?:&PageRequest' arg and return 'Page<?>'
    #[html_sql("example/example.html")]
    async fn select_by_condition(rb: &mut dyn Executor, page_req: &PageRequest, name: &str) -> Page<BizActivity> { impled!() }
use once_cell::sync::Lazy;
pub static RB:Lazy<Rbatis> = 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<BizActivity> {}'
///
#[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<BizActivity> {}

#[tokio::test]
pub async fn test_macro() {
    fast_log::init(fast_log::Config::new().console());
    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

  • discussions

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

捐赠

zxj347284221

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

zxj347284221

rbatis's People

Contributors

chrislearn avatar ggggxiaolong avatar insanebaba avatar jzow avatar kaoimin avatar lzm420241 avatar minghuaw avatar pickfire avatar pymongo avatar quake avatar umaynit avatar uuz2333 avatar xdevs23 avatar zhuxiujia avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.