Rust语言从入门到精通系列 - SeaORM框架实战(数据库DML篇) - 掘金 (juejin.cn)
2027-07-16 start:
Database Connection | SeaORM An async & dynamic ORM for Rust (sea-ql.org)
项目截图:
整个项目的名称:seaorm_test
二进制项目名:tester
lib项目名:tester-lib(暂时是一个空crate)
总Cargo.toml:
[workspace]
resolver = "2"
members = [
"tester"
, "tester-lib"]
tester的Cargo.toml:
[package]
name = "tester"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sea-orm = { version = "0.12.15", features = [ "sqlx-mysql", "runtime-tokio-rustls", "macros" ] }
tokio = {version="1.38.0",features=["full"]}
[lib]
name = "db_lib"
path = "src/db_lib/mod.rs"
tester-lib的Cargo.toml:
[package]
name = "tester-lib"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
main.rs:
use std::error::Error;
use sea_orm::{entity::prelude::*, Database};
use db_lib::wallpaper_type_model::Entity as WallpaperType;
#[tokio::main]
async fn main()->Result<(),Box<dyn Error>> {
let db: DatabaseConnection = Database::connect("protocol://username:password@host/database").await?;
let res =WallpaperType::find().all(&db).await?;
for wallpaper_type in res {
let name = wallpaper_type.type_name.unwrap();
println!("{:?}",name);
}
Ok(())
}
mod.rs:
pub mod wallpaper_type_model;
wallpaper_type_models.rs:
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "wallpaper_type")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub type_name: Option<String>,
pub type_url: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
}
impl ActiveModelBehavior for ActiveModel {}
分页的用法 start:
安装rust二进制库:Using sea-orm-cli | SeaORM An async & dynamic ORM for Rust (sea-ql.org)
cargo install sea-orm-cli
sea-orm-cli generate entity -u mysql://root:123456@127.0.0.1:3306/test -o entity/src --expanded-format
执行完上面的代码后就能够在entity/src下生成实体代码了,然后把生成的代码复制到db_lib目录中,之前的代码就可以删除了
然后我们在一个实体中写测试代码:
wallpaper_detail.rs:
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.15
use sea_orm::entity::prelude::*;
#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity;
impl EntityName for Entity {
fn table_name(&self) -> &str {
"wallpaper_detail"
}
}
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]
pub struct Model {
pub id: i32,
pub wallpaper_name: String,
pub wallpaper_list_url: String,
pub wallpaper_type: i32,
pub remark: String,
pub wallpaper_detail_url: String,
pub wallpaper_detail_click_url: String,
pub wallpaper_list_width: Option<i32>,
pub wallpaper_list_height: Option<i32>,
pub wallpaper_detail_width: Option<i32>,
pub wallpaper_detail_height: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
Id,
WallpaperName,
WallpaperListUrl,
WallpaperType,
Remark,
WallpaperDetailUrl,
WallpaperDetailClickUrl,
WallpaperListWidth,
WallpaperListHeight,
WallpaperDetailWidth,
WallpaperDetailHeight,
}
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
Id,
}
impl PrimaryKeyTrait for PrimaryKey {
type ValueType = i32;
fn auto_increment() -> bool {
true
}
}
#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {}
impl ColumnTrait for Column {
type EntityName = Entity;
fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Integer.def(),
Self::WallpaperName => ColumnType::String(Some(90u32)).def(),
Self::WallpaperListUrl => ColumnType::String(Some(255u32)).def(),
Self::WallpaperType => ColumnType::Integer.def(),
Self::Remark => ColumnType::String(Some(255u32)).def(),
Self::WallpaperDetailUrl => ColumnType::String(Some(255u32)).def(),
Self::WallpaperDetailClickUrl => ColumnType::String(Some(255u32)).def(),
Self::WallpaperListWidth => ColumnType::Integer.def().null(),
Self::WallpaperListHeight => ColumnType::Integer.def().null(),
Self::WallpaperDetailWidth => ColumnType::Integer.def().null(),
Self::WallpaperDetailHeight => ColumnType::Integer.def().null(),
}
}
}
impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
panic!("No RelationDef")
}
}
impl ActiveModelBehavior for ActiveModel {}
#[cfg(test)]
mod tests {
use std::error::Error;
use sea_orm::{Condition, Database, DatabaseConnection, EntityTrait, PaginatorTrait, QueryFilter};
use crate::prelude;
use super::*;
#[tokio::test]
async fn test_detail() ->Result<(),Box<dyn Error>> {
let db: DatabaseConnection = Database::connect("mysql://root:123456@127.0.0.1:3306/test").await?;
let s = String::from("%迪丽%");
let mut page = 5;
let page_size = 10;
let res = prelude::WallpaperDetail::find()
.filter(
Condition::all()
.add(crate::wallpaper_detail::Column::WallpaperName.like(&s))
)
.paginate(&db, page_size);
let page_num = res.num_pages().await?;
if page > page_num || page < 1 {
page = 1;
}
let limit = page -1;
let vecs = res.fetch_page(limit).await?;
for v in vecs {
println!("{:?}:{:?}",v.wallpaper_name,v.wallpaper_detail_url)
}
// 当前页码
println!("当前页码:{:?}",page);
// 总数量
println!("总数量:{:?}",res.num_items().await?);
// 页面数量
println!("页面数量:{:?}",page_num);
Ok(())
}
}
main.rs:
use std::error::Error;
use db_lib::prelude;
use sea_orm::{entity::prelude::*, Condition, Database, DbBackend, QueryTrait};
#[tokio::main]
async fn main()->Result<(),Box<dyn Error>> {
let db: DatabaseConnection = Database::connect("").await?;
// 查询所有数据
// let res =WallpaperType::find().all(&db).await?;
// for wallpaper_type in res {
// let name = wallpaper_type.type_name.unwrap();
// println!("{:?}",name);
// }
let s = String::from("%美女%");
let mut res = prelude::WallpaperDetail::find()
.filter(
Condition::all()
.add(db_lib::wallpaper_detail::Column::WallpaperName.like(&s))
)
.paginate(&db, 100);
println!("{}",prelude::WallpaperDetail::find()
.filter(
Condition::all()
.add(db_lib::wallpaper_detail::Column::WallpaperName.like(&s))
)
.build(DbBackend::MySql)
.to_string()
);
// println!("{:?}",res);
if let Some(values) = res.fetch_and_next().await? {
for v in values {
println!("{:?}:{:?}",v.wallpaper_name,v.wallpaper_detail_url)
}
}
// 总数量
println!("{:?}",res.num_items().await?);
// 页面数量
println!("{:?}",res.num_pages().await?);
Ok(())
}
end
end