• Rust之Sea-orm快速入门指南


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

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

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

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

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

    初始化一个新项目

    1. cargo new seaorm_demo --lib
    2. cd seaorm_demo

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

    文件:Cargo.toml

    1. [dependencies]
    2. tokio = { version = "1.20", features = ["macros", "rt-multi-thread"] }
    3. [dependencies.sea-orm]
    4. version = "0.9"
    5. features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ]
    6. default-features = false

    安装 sea-orm-cli 和迁移

    cargo install sea-orm-cli

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

    sea-orm-cli migrate init
    

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

    1. .
    2. ├── Cargo.lock
    3. ├── Cargo.toml
    4. ├── migration
    5. │ ├── Cargo.toml
    6. │ ├── README.md
    7. │ └── src
    8. │ ├── lib.rs
    9. │ ├── m20220101_000001_create_table.rs
    10. │ └── main.rs
    11. └── src
    12. └── lib.rs

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

    文件:migration/Cargo.toml

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

    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

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

    生成的实体应如下所示。

    文件:entity/src/post.rs

    1. //! SeaORM Entity. Generated by sea-orm-codegen 0.9.0
    2. use sea_orm::entity::prelude::*;
    3. #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
    4. #[sea_orm(table_name = "post")]
    5. pub struct Model {
    6. #[sea_orm(primary_key)]
    7. pub id: i32,
    8. pub title: String,
    9. pub text: String,
    10. }
    11. #[derive(Copy, Clone, Debug, EnumIter)]
    12. pub enum Relation {}
    13. impl RelationTrait for Relation {
    14. fn def(&self) -> RelationDef {
    15. panic!("No RelationDef")
    16. }
    17. }
    18. 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

    1. [workspace]
    2. members = [".", "entity", "migration"]
    3. [dependencies]
    4. entity = { path = "entity" }
    5. migration = { path = "migration" }

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

    1. .
    2. ├── Cargo.lock
    3. ├── Cargo.toml
    4. ├── entity
    5. │ ├── Cargo.toml
    6. │ └── src
    7. │ ├── lib.rs
    8. │ ├── post.rs
    9. │ └── prelude.rs
    10. ├── migration
    11. │ ├── Cargo.lock
    12. │ ├── Cargo.toml
    13. │ ├── README.md
    14. │ └── src
    15. │ ├── lib.rs
    16. │ ├── m20220101_000001_create_table.rs
    17. │ └── main.rs
    18. ├── src
    19. │ └── lib.rs
    20. └── migration.pdb

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

    文件:Cargo.tmol

    1. [package]
    2. name = "seaorm_demo"
    3. version = "0.1.0"
    4. edition = "2021"
    5. [workspace]
    6. members = [".", "entity", "migration"]
    7. [dependencies]
    8. entity = { path = "entity" }
    9. migration = { path = "migration" }
    10. tokio = { version = "1.20", features = ["macros", "rt-multi-thread"] }
    11. [dependencies.sea-orm]
    12. version = "0.9"
    13. features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ]
    14. default-features = false

    连接数据库

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

    文件:src/lib.rs

    1. use migration::{DbErr, Migrator, MigratorTrait};
    2. use sea_orm::{Database, DbConn};
    3. const DATABASE_URL: &str = "postgres://root:root@localhost:5432/axum_example";
    4. pub async fn establish_connection() -> Result {
    5. let db = Database::connect(DATABASE_URL)
    6. .await
    7. .expect("连接数据库失败");
    8. Migrator::up(&db, None)
    9. .await
    10. .expect("迁移失败");
    11. Ok(db)
    12. }

    “增”-添加数据

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

    文件:src/bin/create_post.rs

    1. use migration::DbErr;
    2. use sea_orm::{Set, ActiveModelTrait};
    3. use seaorm_demo::establish_connection;
    4. use entity::post;
    5. #[tokio::main]
    6. async fn main() -> Result<(), DbErr>{
    7. let db = establish_connection().await?;
    8. let post = post::ActiveModel {
    9. title: Set(String::from("我是title")),
    10. text: Set(String::from("我是text")),
    11. ..Default::default()
    12. };
    13. let post: post::Model = post.insert(&db).await?;
    14. println!("ID: {}, title: {}", post.id, post.title);
    15. Ok(())
    16. }

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

    cargo run --bin create_post
    

    应该如下所示。

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

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

    我会再创造一个。

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

    “查”——表单查询

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

    文件:src/bin/read_posts.rs

    1. use migration::DbErr;
    2. use sea_orm::EntityTrait;
    3. use seaorm_demo::establish_connection;
    4. use entity::post;
    5. #[tokio::main]
    6. async fn main() -> Result<(), DbErr>{
    7. let db = establish_connection().await?;
    8. let posts: Vec = post::Entity::find().all(&db).await?;
    9. println!("表中的所有帖子:");
    10. for post in posts {
    11. println!("id: {}, title: {}", post.id, post.title);
    12. }
    13. Ok(())
    14. }

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

    cargo run --bin read_posts

    应该如下所示。

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

    “改”——更新数据

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

    文件:src/bin/update_post.rs

    1. use migration::DbErr;
    2. use sea_orm::{EntityTrait, Set, ActiveModelTrait};
    3. use seaorm_demo::establish_connection;
    4. use entity::post;
    5. #[tokio::main]
    6. async fn main() -> Result<(), DbErr>{
    7. let db = establish_connection().await?;
    8. //根据ID更新帖子内容
    9. let post = post::Entity::find_by_id(1).one(&db).await?;
    10. let mut post: post::ActiveModel = post.unwrap().into();
    11. post.title = Set("哈哈,我被更新啦".to_owned());
    12. let post: post::Model = post.update(&db).await?;
    13. println!("更新后的帖子id: {} title: {}", post.id, post.title);
    14. Ok(())
    15. }

    我们运行这个脚本

    cargo run --bin update_post
    

    应该如下所示。

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

    “删”——删除数据

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

    我们将删除 ID 为 1 的帖子

    文件:src/bin/delete_post.rs

    1. use migration::DbErr;
    2. use sea_orm::{EntityTrait, DeleteResult, ModelTrait};
    3. use seaorm_demo::establish_connection;
    4. use entity::post;
    5. #[tokio::main]
    6. async fn main() -> Result<(), DbErr>{
    7. let db = establish_connection().await?;
    8. let post = post::Entity::find_by_id(1).one(&db).await?;
    9. let post: post::Model = post.unwrap();
    10. let res: DeleteResult = post.delete(&db).await?;
    11. assert_eq!(res.rows_affected, 1);
    12. println!("{:?}", res);
    13. Ok(())
    14. }

    我们将调用这个脚本

    cargo run --bin delete_post
    

    应该如下所示。

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

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

    1. $ cargo run --bin read_posts
    2. Finished dev [unoptimized + debuginfo] target(s) in 0.31s
    3. Running `target/debug/read_posts`
    4. ID: 2, title: 我是title

  • 相关阅读:
    MP进阶操作: 时间操作, sql,querywapper,lambdaQueryWapper(条件构造器)快速筛选 枚举类
    Android AMS——栈管理基础(九)
    原型和原型链
    学习python第一天(数据类型)
    postgresql 行转列的例子
    回归预测 | MATLAB实现基于RF随机森林的工业增加值预测(多因素、多指标)
    系统架构师备考倒计时24天(每日知识点)
    leetCode递增子序列
    适用于 .NET 的现代化、流畅、可测试的HTTP客户端库
    <leetcode>35.搜索插入位置——二分法
  • 原文地址:https://blog.csdn.net/love906897406/article/details/126642259