< 返回版块

zhuxiujia 发表于 2022-08-17 10:33

Tags:【编译时 ORM rbatis V4.0 现已发布!第1篇】

经过几个月的迭代,编译时 ORM RBatis 已经更新到V4。这篇文章详细介绍了我们的策略和动机

V4 移除了 Wrapper

首先,我认为包装器对于静态分析没有任何好处,很容易将数据库相关的查询逻辑混入到实际的生产业务逻辑中。此外,在 V3 包装器中,它甚至包括一些数据库方言,例如分页(在 mysql、Postgres、MSSQL 中)几乎都不同。我们决定删除包装器并添加 CRUD!宏。我们认为静态生成的宏有利于源代码分析,并且强制将数据库相关的逻辑移动到一个模块中,而不是分散在所有模块中,保持简单,不失可扩展性。是一项壮举。

去掉 sqlx-core,添加 rbdc数据库抽象驱动

我们不是故意制造分裂。很多异步ORM都会选择直接依赖sqlx,包括rbatis-v3的版本。我们之所以选择fork是为了支持——可扩展性、序列化、干净。

  • 为了可扩展性 关于可扩展性,我们可以观察golang标准版的数据库包和Java的jdbc驱动。它们具有极好的可扩展性。 而sqlx似乎更喜欢使用泛型和确定性条件编译来区分数据库驱动类型,并添加任何类型的驱动程序(然而,令人失望的是任何驱动程序只使用条件编译来区分支持的四种驱动类型)这意味着很难扩展和支持其他数据库类型或其他优秀的ht​​tps ://crates.io/项。同时也带来了复杂的条件编译来解决依赖隔离。 想象一下,如果有可以扩展的驱动类型,你可以把数据库驱动(https://crates.io/crates/tokio-postgres)写成驱动抽象,你只需要调用驱动抽象方法。是的,那么我们可以只重写数据库驱动的抽象。我们甚至调查了GitHub - tokio-rs/rdbc:Rust DataBase Connectivity (RDBC) :: Common Rust API for database drivers(它似乎不是为异步设计的),尽管它试图抽象数据库驱动程序。

就像tiberius,这个 crates 比 sqlx 的 mssql 类型要好。我们添加crates rbdc-mssql

就像tokio-postgres,它可能是一个性能出色的库,你只需要实现rbdc::db 包下面几个trait即可接入驱动到rbatis

据我所知,有很多优秀的库。我们需要做的是支持他们加入驱动抽象,而不是自己创建库,因为我们驱动的支持可能不如他们的

  • 为了序列化 上面提到的GitHub - tokio-rs/rdbc: Rust DataBase Connectivity (RDBC) :: Common Rust API for database drivers尝试创建一个抽象的数据库驱动程序,然后我认为它的错误也是如此。不能完全确定所有的数据库类型,甚至有些数据库正在创建新的数据库类型。因此,我认为最终的解决方案是创建一个适合 ORM 的序列化框架,并添加 ext 类型以扩展到任何类型。 所以。我们添加序列化库 rbs

  • 为了清洁 我认为当一个项目变成粪堆时,是因为堆叠了太多无关的功能。 所以驱动只做了两件事,method exec 和 method query。没有奇怪的 logging crates 导致多语言失败, 没有没有硬编码的 explan 语句。

本介绍暂时结束,但对现代编译时ORM的介绍尚未完成。在接下来的介绍中:

Num-2 rbatis设计概念,与mybatis3兼容,无污染表结构定义

Num-3适用于orm---rbs的rbatis序列化框架

Num-4 rbatis自动表创建插件table_sync

Num-5 rbatis py_sql/html_sql解析、翻译、代码生成rbatis codegen

Num-6独立驱动器和动态调整的连接池


Ext Link: https://users.rust-lang.org/t/rbatis-v4-0-is-out-num-1/79973

评论区

写评论
‘static 2022-08-18 11:49

可以了,非常感谢!

--
👇
zhuxiujia: 这个问题已修复,更新即可

--
👇
‘static: pg驱动有问题:condition 参数:Map({String("name"): String("王大锤"), String("group_ids"): Array([U64(9), U64(11)])}) 日志:[rbatis] [402469920169922560] Fetch ==> select * from t_user where state_flag=0 and group_id in (?,?) AND name like '%'||?||'%' order by id desc [rbatis] Args ==> [9,11,"王大锤"] db:Notice { storage: b"SERROR\0VERROR\0C22P03\0Mincorrect binary data format in bind parameter 1\0Wunnamed portal parameter $1\0Fpostgres.c\0L1894\0Rexec_bind_message\0\0", severity: Error, message: (22, 70), code: (15, 20) }

#[py_sql(
    rb,
    "`select * from t_user where state_flag=0 `
     and group_id in (
     trim ',': for id in condition.group_ids:
         #{id},
     )
     if  condition.name != '':
        ` AND name like '%'||#{condition.name}||'%'`
     ` order by id desc`
    "
)]
pub async fn get_users(
    rb: &Rbatis,
    condition: &rbs::Value,

    page: &PageRequest,
) -> Page<User> {
    todo!()
}
作者 zhuxiujia 2022-08-18 00:44

这个问题已修复,更新即可

--
👇
‘static: pg驱动有问题:condition 参数:Map({String("name"): String("王大锤"), String("group_ids"): Array([U64(9), U64(11)])}) 日志:[rbatis] [402469920169922560] Fetch ==> select * from t_user where state_flag=0 and group_id in (?,?) AND name like '%'||?||'%' order by id desc [rbatis] Args ==> [9,11,"王大锤"] db:Notice { storage: b"SERROR\0VERROR\0C22P03\0Mincorrect binary data format in bind parameter 1\0Wunnamed portal parameter $1\0Fpostgres.c\0L1894\0Rexec_bind_message\0\0", severity: Error, message: (22, 70), code: (15, 20) }

#[py_sql(
    rb,
    "`select * from t_user where state_flag=0 `
     and group_id in (
     trim ',': for id in condition.group_ids:
         #{id},
     )
     if  condition.name != '':
        ` AND name like '%'||#{condition.name}||'%'`
     ` order by id desc`
    "
)]
pub async fn get_users(
    rb: &Rbatis,
    condition: &rbs::Value,

    page: &PageRequest,
) -> Page<User> {
    todo!()
}
‘static 2022-08-17 22:36

pg驱动有问题:condition 参数:Map({String("name"): String("王大锤"), String("group_ids"): Array([U64(9), U64(11)])}) 日志:[rbatis] [402469920169922560] Fetch ==> select * from t_user where state_flag=0 and group_id in (?,?) AND name like '%'||?||'%' order by id desc [rbatis] Args ==> [9,11,"王大锤"] db:Notice { storage: b"SERROR\0VERROR\0C22P03\0Mincorrect binary data format in bind parameter 1\0Wunnamed portal parameter $1\0Fpostgres.c\0L1894\0Rexec_bind_message\0\0", severity: Error, message: (22, 70), code: (15, 20) }

#[py_sql(
    rb,
    "`select * from t_user where state_flag=0 `
     and group_id in (
     trim ',': for id in condition.group_ids:
         #{id},
     )
     if  condition.name != '':
        ` AND name like '%'||#{condition.name}||'%'`
     ` order by id desc`
    "
)]
pub async fn get_users(
    rb: &Rbatis,
    condition: &rbs::Value,

    page: &PageRequest,
) -> Page<User> {
    todo!()
}
作者 zhuxiujia 2022-08-17 17:50

是因为遗留代码对arg关键字做了处理,你再跑一下cargo update 即可解决

--
👇
‘static: 以前的查询条件,为了通用,所以使用bson ,json 之类的数据接收的,使用rbson 在3.0正常,使用4.0提示:move occurs because value has type Value, which does not implement the Copy trait

#[py_sql(
    "`select * from biz_activity where delete_flag = 0`
                  if arg.name != '':
                    ` and name=#{arg.name}`"
)]
async fn py_select_page_by_json(
    rb: &mut dyn Executor,
    arg: &mut Value,
) -> Result<Vec<BizActivity>, Error> {
    impled!()
}

 let mut value_map = ValueMap::new();
    value_map.insert("name".into(), "test".into());
    let mut arg = to_value(value_map).unwrap();
    let a = py_select_page_by_json(&mut rb.clone(), &mut arg)
        .await
        .unwrap();
    println!(">>>>>>>>>>>> {:?}", a);
}

--
👇
zhuxiujia: 可以参考这个复杂点的项目 https://github.com/rbatis/abs_admin

--
👇
‘static: 大佬,整个复杂点的py_sql样例。以前3.0的代码,升级不上去

‘static 2022-08-17 15:17

以前的查询条件,为了通用,所以使用bson ,json 之类的数据接收的,使用rbson 在3.0正常,使用4.0提示:move occurs because value has type Value, which does not implement the Copy trait

#[py_sql(
    "`select * from biz_activity where delete_flag = 0`
                  if arg.name != '':
                    ` and name=#{arg.name}`"
)]
async fn py_select_page_by_json(
    rb: &mut dyn Executor,
    arg: &mut Value,
) -> Result<Vec<BizActivity>, Error> {
    impled!()
}

 let mut value_map = ValueMap::new();
    value_map.insert("name".into(), "test".into());
    let mut arg = to_value(value_map).unwrap();
    let a = py_select_page_by_json(&mut rb.clone(), &mut arg)
        .await
        .unwrap();
    println!(">>>>>>>>>>>> {:?}", a);
}

--
👇
zhuxiujia: 可以参考这个复杂点的项目 https://github.com/rbatis/abs_admin

--
👇
‘static: 大佬,整个复杂点的py_sql样例。以前3.0的代码,升级不上去

作者 zhuxiujia 2022-08-17 13:52

可以参考这个复杂点的项目 https://github.com/rbatis/abs_admin

--
👇
‘static: 大佬,整个复杂点的py_sql样例。以前3.0的代码,升级不上去

‘static 2022-08-17 13:19

大佬,整个复杂点的py_sql样例。以前3.0的代码,升级不上去

Mike Tang 2022-08-17 12:02

So extremely cool!

1 共 8 条评论, 1 页