#sqlite #postgresql #mysql #async-orm #orm

cherry

A Rust 异步 ORM,支持 MySQL、PostgreSQL 和 SQLite

1 个不稳定版本

0.4.0 2022年12月29日
0.3.0 2022年6月20日
0.2.2 2021年11月10日
0.1.1 2021年10月24日
0.0.0 2021年10月22日

#1315数据库接口

每月 25 次下载

MIT/Apache

63KB
1.5K SLoC

Cherry 🍒

Cherry 是一个基于 SQLx 的 Rust 异步 ORM,支持 MySQL、PostgreSQL 和 SQLite。它设计得易于使用。

必需功能

数据库

至少启用以下功能之一: sqlitepostgresmysql

异步运行时

  • async-std: runtime-async-std-native-tlsruntime-async-std-rustls
  • tokio: runtime-tokio-native-tlsruntime-tokio-rustls
  • actix: runtime-actix-native-tlsruntime-actix-rustls

异步运行时仅适用于 mysqlpostgres

例如,假设您选择 sqlitemysql 和异步运行时 runtime-async-std-rustls,则 toml 依赖项应如下所示

[dependencies]
cherry = { version = "0.4.0", features = ["sqlite", "mysql", "runtime-async-std-rustls"] }

示例

use cherry::{Cherry, QueryExecutor};
use cherry::clause::Where;
use cherry::sqlite::SqlitePool;
// use cherry::mysql::MySqlPool;

#[derive(Cherry)]
struct User {
    id: u32,
    name: String,
}

async fn example() {
    let pool = SqlitePool::connect("sqlite::memory:").await.unwrap();
    // let pool = MySqlPool::connect("mysql://username:password@localhost/test").await.unwrap();

    let user = User { id: 100, name: "Joe" };
    let result = user.insert().execute(&pool).await.unwrap();
    assert_eq!(1, result.rows_affected);

    let result = User::select().and_eq("id", &user.id).one(&pool).await.unwrap();
    assert!(result.is_some());
    assert_eq!(user.name, result.unwrap().name);
}

插入

// Insert one
let user = User { id: 100, name: "Joe" };
let result = user.insert().execute(&pool).await?;
assert_eq!(1, result.rows_affected);

// Insert multiple
let users = vec![ /*...*/];
User::insert_bulk(&users).execute(&pool).await?;

// Insert ignore on conflict
User::insert_bulk(&users).ignore_on_conflict().execute(&pool).await?;

// Insert update columns if the column "id" conflict (valid for sqlite and postgres)
User::insert_bulk(&users).update_on_conflict().conflict_column("id").set_column("name").set_column("age").execute(&pool).await?;

// Insert or replace if the column "id" conflict (valid for sqlite and mysql, only sqlite can 
specify conflict column)
User::insert_bulk(&users).replace_on_conflict().execute(&pool).await?;

选择

// Select one
let user: Option<User> = User::select().and_eq("id", 100).one(&pool).await?;

// Select in list
let users: Vec<User> = User::select().and_gt("id", 100).all(&pool).await?;

// Select in tuple
let count: Option<(u64,)> = User::select().column_raw("COUNT(*)").tuple(&pool).await?;

// Wrap conditions
// WHERE (id < 100 OR id > 200) AND age > 25
User::select().and(|c| c.or_lt_ref("id", 100).or_gt_ref("id", 200)).and_gt("age", 25).all(&pool)
await?;

更新

User::update().set("name", "Sleepy").and_eq("id", 100).execute(&pool).await?;

删除

User::delete().and_eq("id", 100).execute(&pool).await?;

事务

let mut tx = pool.begin().await?;
User::insert_bulk(&users).execute(&mut tx).await?;
User::update().set("name", "Sleepy").and_eq("id", 100).execute(&mut tx).await?;
tx.commit().await?;

更多

自定义表名

// Change the default table name "user" to "people"

#[derive(Cherry)]
#[cherry(table = "people")]
struct User {
    // fields..
}

指定特定数据库

默认情况下,Cherry 将为您的实体实现所有数据库类型。由于某种原因,您可以指定实体的特定数据库类型。

如下,cherry 将为 "User" 实体实现 "mysql" 和 "postgres" 两者

[dependencies]
cherry = { version = "0.4.0", features = ["postgres", "mysql", "runtime-async-std-rustls"] }

这将只为 "User" 实体实现 "mysql"

#[derive(Cherry)]
#[cherry(database = "mysql")]
struct User {
    // fields..
}

依赖项

~9–28MB
~481K SLoC