Rust之Sea-orm快速入门指南

SeaORM 是一种关系 ORM,可帮助您使用
熟悉的动态语言在 Rust 中构建 Web 服务。

SeaORM 的官方文档在他们的官方网站上

本指南使用的是 PostgreSQL在我们开始之前,请确保您
已经为您的系统安装了
PostgreSQL

在本次教程中,我们将构建每个 CRUD 操作的简单示例。

我正在使用Rust v1.62 和sea-ormv0.9

初始化一个新项目

cargo new seaorm_demo --lib
cd seaorm_demo

首先,让我们将 SeaORM 和 tokio 添加到我们的依赖项中。

文件:Cargo.toml

[dependencies]
tokio = { version = "1.20", features = ["macros", "rt-multi-thread"] }

[dependencies.sea-orm]
version = "0.9"
features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ]
default-features = false

安装 sea-orm-cli 和迁移

cargo install sea-orm-cli

我们将编写一个迁移文件来设置我们的数据库和表模式。

sea-orm-cli migrate init

接下来会生成一个名为migration的目录  现在我们的项目结构应该是这样的。

.
├── Cargo.lock
├── Cargo.toml
├── migration
│   ├── Cargo.toml
│   ├── README.md
│   └── src
│       ├── lib.rs
│       ├── m20220101_000001_create_table.rs
│       └── main.rs
└── src
    └── lib.rs

打开文件migration/Cargo.toml并取消最后两行注释sea-orm-migration.

文件:migration/Cargo.toml

[dependencies.sea-orm-migration]
version = "^0.9.0"
features = [
  # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
  # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
  # e.g.
   "runtime-tokio-rustls",  # `ASYNC_RUNTIME` featrure
   "sqlx-postgres",         # `DATABASE_DRIVER` feature
]

migration/src/m20220101_000001_create_table.rs在您喜欢的编辑器中编辑文件
并删除两个
todo!()"保存。

在项目根目录新建一个".env"文件

DATABASE_URL="postgres://root:root@localhost:5432/axum_example"

接下来,我们将运行迁移。

sea-orm-cli migrate up

它将编译migration模块并运行您的迁移。在此之后,您
应该会在您的目录中看到一个名为 posts.pdb的文件。

生成实体

创建一个新entity模块。

cargo new entity --lib

接下来,生成实体。

sea-orm-cli generate entity -o entity/src

sea-orm依赖项添加到entity模块。

文件:entity/Cargo.toml

[dependencies]
sea-orm = { version = "0.9" }

生成的实体应如下所示。

文件:entity/src/post.rs

//! SeaORM Entity. Generated by sea-orm-codegen 0.9.0

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "post")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub title: String,
    pub text: String,
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {}

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        panic!("No RelationDef")
    }
}

impl ActiveModelBehavior for ActiveModel {}

由于模块entity位于我们项目的根目录,我们将lib.rs删除掉,然后把mod.rs转换
为库,以便我们可以使用它。

重命名entity/src/mod.rsentity/src/lib.rs.

mv entity/src/mod.rs entity/src/lib.rs

接下来,我们将entitymigration库添加到
根项目的依赖项中。

文件:Cargo.toml

[workspace]
members = [".", "entity", "migration"]

[dependencies]
entity = { path = "entity" }
migration = { path = "migration" }

现在你的项目结构应该看起来像这样的

.
├── Cargo.lock
├── Cargo.toml
├── entity
│   ├── Cargo.toml
│   └── src
│       ├── lib.rs
│       ├── post.rs
│       └── prelude.rs
├── migration
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── README.md
│   └── src
│       ├── lib.rs
│       ├── m20220101_000001_create_table.rs
│       └── main.rs
├── src
│   └── lib.rs
└── migration.pdb

项目Cargo.toml应该如下所示。

文件:Cargo.tmol

[package]
name = "seaorm_demo"
version = "0.1.0"
edition = "2021"

[workspace]
members = [".", "entity", "migration"]

[dependencies]
entity = { path = "entity" }
migration = { path = "migration" }
tokio = { version = "1.20", features = ["macros", "rt-multi-thread"] }

[dependencies.sea-orm]
version = "0.9"
features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ]
default-features = false

连接数据库

现在我们编写代码来建立与数据库的连接。

文件:src/lib.rs

use migration::{DbErr, Migrator, MigratorTrait};
use sea_orm::{Database, DbConn};
const DATABASE_URL: &str = "postgres://root:root@localhost:5432/axum_example";

pub async fn establish_connection() -> Result<DbConn, DbErr> {
    let db = Database::connect(DATABASE_URL)
        .await
        .expect("连接数据库失败");
    Migrator::up(&db, None)
        .await
        .expect("迁移失败");

    Ok(db)
}

“增”-添加数据

现在让我们编写一些代码来创建帖子。创建一个新文件src/bin/create_post.rs

文件:src/bin/create_post.rs

use migration::DbErr;
use sea_orm::{Set, ActiveModelTrait};
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    let post = post::ActiveModel {
        title: Set(String::from("我是title")),
        text: Set(String::from("我是text")),
        ..Default::default()
    };

    let post: post::Model = post.insert(&db).await?;

    println!("ID: {}, title: {}", post.id, post.title);

    Ok(())
}

我们可以如下运行我们的新脚本。

cargo run --bin create_post

应该如下所示。

$ cargo run --bin create_post
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 3.85s
     Running `target/debug/create_post`
ID: 1, title: 我是title

如果您希望在数据库中创建更多条目,请更改标题/文本
create_post.rs并再次执行脚本。

我会再创造一个。

$ cargo run --bin create_post
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 4.08s
     Running `target/debug/create_post`
ID: 2, title: 我是title

“查”——表单查询

接下来,我们编写读取数据库中所有帖子的示例。

文件:src/bin/read_posts.rs

use migration::DbErr;
use sea_orm::EntityTrait;
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    let posts: Vec<post::Model> = post::Entity::find().all(&db).await?;

    println!("表中的所有帖子:");
    for post in posts {
        println!("id: {}, title: {}", post.id, post.title);
    }

    Ok(())
}

就像之前一样,您可以按如下方式运行这个新文件。

cargo run --bin read_posts

应该如下所示。

$ cargo run --bin read_posts
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 4.08s
     Running `target/debug/read_posts`
表中的所有帖子:
ID: 1, title : 我是title
ID: 2, title : 我是title

“改”——更新数据

现在,假设我们想要对帖子的标题执行 UPDATE 操作。

文件:src/bin/update_post.rs

use migration::DbErr;
use sea_orm::{EntityTrait, Set, ActiveModelTrait};
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    //根据ID更新帖子内容
    let post = post::Entity::find_by_id(1).one(&db).await?;
    let mut post: post::ActiveModel = post.unwrap().into();
    post.title = Set("哈哈,我被更新啦".to_owned());
    let post: post::Model = post.update(&db).await?;

    println!("更新后的帖子id: {}  title: {}", post.id, post.title);

    Ok(())
}

我们运行这个脚本

cargo run --bin update_post

应该如下所示。

$ cargo run --bin update_post                                                                                         ⏎
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 2.80s
     Running `target/debug/update_post`
更新后的帖子id:1  title: 哈哈,我被更新啦

“删”——删除数据

现在进行最后的操作,删除。创建一个新文件src/bin/delete_post.rs

我们将删除 ID 为 1 的帖子

文件:src/bin/delete_post.rs

use migration::DbErr;
use sea_orm::{EntityTrait, DeleteResult, ModelTrait};
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    let post = post::Entity::find_by_id(1).one(&db).await?;
    let post: post::Model = post.unwrap();

    let res: DeleteResult = post.delete(&db).await?;
    assert_eq!(res.rows_affected, 1);

    println!("{:?}", res);

    Ok(())
}

我们将调用这个脚本

cargo run --bin delete_post

应该如下所示。

$ cargo run --bin delete_post
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 5.42s
     Running `target/debug/delete_post`
DeleteResult { rows_affected: 1 }

我们可以再次执行脚本read_post来查看数据库中还有哪些帖子。

$ cargo run --bin read_posts 
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/read_posts`

ID: 2, title: 我是title

猜你喜欢

转载自blog.csdn.net/love906897406/article/details/126642259