Rust的ORM框架:rbatis

Rust的ORM框架rbatis使用介绍

rabits 是一个Rust的ORM框架,目前的版本是4,3已经标记为废弃。所以后文所有介绍以及代码示例,均基于版本4。

依赖

现在的rbatis最新版本为4.5.49,所以如果是cargo管理的项目,可以直接在dependencies中添加4.5.49版本,或者更宽泛的版本限制,如4.5。

rbatis依赖rdbc,所以如果需要操作Mysql数据库,可以添加rdbc-mysql的依赖。

如下:

[dependencies]  
rbs = "4.5"
rbatis = "4.5"
rdbc-mysql = "4.5"

根据官方手册,rbatis目前支持任何rdbc驱动,如:

database(crates.io)github_link
Mysqlrbatis/rbdc-mysql
Postgresrbatis/rbdc-pg
Sqliterbatis/rbdc-sqlite
Mssqlrbatis/rbdc-mssql
MariaDBrbatis/rbdc-mysql
TiDBrbatis/rbdc-mysql
CockroachDBrbatis/rbdc-pg
Oraclechenpengfan/rbdc-oracle
TDenginetdcare/rbdc-tdengine

rbatis还支持不同的功能选项,比如为了方便调试,可以打开调试选项degug_mode:

[dependencies]
rbatis = {version = "4.5", features = ["debug_mode"]}  

另外,如果使用crud等宏来定义SQL,Cargo.toml里就需要添加上rbs。

按照手册上所言,rbs是由rbatis的实现的一个序列化库,但是我去掉这个依赖以后,curd、impl_select等都报错了。

经过查看rbatis源码,发现crud、impl_select等宏的实现都使用了rbs做的序列化。如impl_insert的实现:

#[macro_export]
macro_rules! impl_insert {
    ($table:ty{}) => {
        $crate::impl_insert!($table {}, "");
    };
    ($table:ty{},$table_name:expr) => {
        impl $table {
            pub async fn insert_batch(
                executor: &dyn $crate::executor::Executor,
                tables: &[$table],
                batch_size: u64,
            ) -> std::result::Result<$crate::rbdc::db::ExecResult, $crate::rbdc::Error> {
                pub trait ColumnSet {
                    /// take `vec![Table{"id":1}]` columns
                    fn column_sets(&self) -> rbs::Value;
                }
                impl ColumnSet for rbs::Value {
                    fn column_sets(&self) -> rbs::Value {
                        let len = self.len();
                        let mut column_set = std::collections::HashSet::with_capacity(len);
                        if let Some(array) = self.as_array(){
                            for item in array {
                             for (k,v) in &item {
                                if (*v) != rbs::Value::Null{
                                    column_set.insert(k);
                                }
                             }
                            }
                        }
                        let mut columns = rbs::Value::Array(vec![]);
                        if len > 0 {
                            let table = &self[0];
                            let mut column_datas = Vec::with_capacity(table.len());
                            for (column, _) in table {
                                if column_set.contains(&column) {
                                    column_datas.push(column);
                                }
                            }
                            columns = rbs::Value::from(column_datas);
                        }
                        columns
……

很明显,这其中的rbs::Value就是使用的rbs。

使用方法

要把Rust结构,与数据库的记录建立映射,只需要三步

  • 使用Rust语言定义数据的结构
  • 使用rbatis宏定义SQL
  • 使用定义的SQL,映射结构

结构

需要注意的是,Rust结构中,一般的值需要定义成Option,否则rbatis查询不到相应的值,会返回错误。

如我们定义一个用户信息结构UserInfo:

pub struct UserInfo {
    pub id: Option<i64>,
    pub username: Option<String>,
    pub password: Option<String>
}

之后就可以使用rbatis的宏来定义相应的映射了。

SQL

rbatis支持crud!简单定义,也支持impl_select!、impl_update!与impl_delete!等精细化定义。

比如,如果我们简单地实现一个增删改查:

use rbatis;

rbatis::impl_crud!(UserInfo{});

之后,就可以通过UserInfo的方法insert、select_by_column、delete_by_column以及update_by_column这几个方法了。

如:

UserInfo::select_by_column(&rb, "id", "1").await;

其中,方法的第一个参数是一个RBatis实体,需要创建以及连接相应的驱动。

RBatis连接数据库驱动的实现为:

pub async fn link<Driver: rbdc::db::Driver + 'static>(  
    &self,  
    driver: Driver,  
    url: &str,  
) -> Result<(), Error> {  
    self.init(driver, url)?;  
    self.try_acquire().await?;  
    Ok(())  
}

其实就是先使用init初始化,之后调用try_acquire获取一个连接。

比如,我们连接一个Mysql的驱动,即rdbc-mysql,之后再查询上面的UserInfo,可以使用如下代码:

use rbatis::RBatis;  
use rbdc_mysql::MysqlDriver;
use crate::UserInfo;

……

let rb = RBatis::new();

rb.link(MysqlDriver{}, "mysql://127.0.0.1/helloworld").await.unwrap();

let user = UserInfo::select_by_column(&rb, "id", "1").await;
match user {
    ……
}

自定义

如果要进行自定义,可以使用宏的参数。

比如,UserInfo的数据库表不是user_info,而是hello_user_info,则可以使用

rbatis::impl_select!(UserInfo{select_by_id(id:String) -> Option => "`where id = #{id} limit 1`"}, "hello_user_info");

把数据库表绑定到了宏的参数。

或者还可以把表名绑定到最终的方法参数,如:

rbatis::impl_select!(UserInfo{select_by_id(tablename: String, id:String) -> Option => "`where id = #{id} limit 1`"});

之后通过:

let user = UserInfo::select_by_id(&rb, "hello_user_info", "1").await;

来查询。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值