Sea-ORM 不内置“访问器/修改器”语法糖(如自动 Getter/Setter 转换)。推荐实践:
- 访问器:在 Model/VO 上实现方法或
From<T>映射 - 修改器:在 Service 层做参数标准化/校验;在
ActiveModelBehavior::before_save进行落库前处理 - 枚举/类型转换:用
DeriveActiveEnum与serde实现
2024/10/30大约 2 分钟
Sea-ORM 不内置“访问器/修改器”语法糖(如自动 Getter/Setter 转换)。推荐实践:
From<T> 映射ActiveModelBehavior::before_save 进行落库前处理DeriveActiveEnum 与 serde 实现“API 资源”是一种约定:使用专门的 VO/Resource 结构体来组织输出,统一字段、分页与元数据,避免直接把数据库模型暴露到外部。
#[derive(serde::Serialize)]
pub struct UserResource {
pub id: i64,
pub username: String,
pub real_name: Option<String>,
pub dept_name: Option<String>,
}
impl From<(entity::sys_user::Model, Option<entity::sys_dept::Model>)> for UserResource {
fn from((u, d): (entity::sys_user::Model, Option<entity::sys_dept::Model>)) -> Self {
Self {
id: u.id,
username: u.username,
real_name: u.real_name,
dept_name: d.map(|x| x.name),
}
}
}
Sea-ORM 提供丰富的类型映射能力:枚举(ActiveEnum)、JSON、Decimal、数组(PostgreSQL)等。合理建模能提升类型安全与可读性。
use sea_orm::entity::prelude::*;
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize)]
#[sea_orm(rs_type = "String", db_type = "String(Some(20))")]
pub enum UserStatus {
#[sea_orm(string_value = "ENABLED")]
Enabled,
#[sea_orm(string_value = "DISABLED")]
Disabled,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub status: UserStatus, // 强类型字段
}
Sea-ORM 的查询结果通常是 Vec<Model>、(Model, RelatedModel) 元组或自定义投影(FromQueryResult)。本节聚焦“取回后的集合处理”:映射到 VO、分组/索引、构建树、聚合统计、分页归并与并行处理等。
Sea-ORM 提供“硬删除(物理删除)”API。若你的系统采用“软删除”,请参考下一节。
use sea_orm::EntityTrait;
let aff = entity::sys_user::Entity::delete_by_id(id).exec(&db).await?;
let rows = aff.rows_affected;
为避免 N+1 查询,Sea-ORM 提供 LoaderTrait 的批量预加载能力,以及 find_with_related 的聚合查询。
use sea_orm::LoaderTrait;
// 1) 批量查用户
let users = entity::sys_user::Entity::find().all(&db).await?;
// 2) 预加载所属部门(多对一)
let depts: Vec<Option<entity::sys_dept::Model>> = users.load_one(entity::sys_dept::Entity, &db).await?;
// 3) 预加载用户的角色(多对多)
let roles: Vec<Vec<entity::sys_role::Model>> = users.load_many(entity::sys_role::Entity, &db).await?;
// 4) 组装 VO
#[derive(serde::Serialize)]
struct UserWithRel {
user: entity::sys_user::Model,
dept: Option<entity::sys_dept::Model>,
roles: Vec<entity::sys_role::Model>,
}
let items: Vec<UserWithRel> = users.into_iter().zip(depts).zip(roles)
.map(|((u, d), rs)| UserWithRel { user: u, dept: d, roles: rs })
.collect();
通过 ActiveModelBehavior 可以在持久化生命周期内挂钩,典型用途:
use sea_orm::{ActiveModelBehavior, DbErr, ActiveValue::Set};
impl ActiveModelBehavior for entity::sys_user::ActiveModel {
fn before_save(mut self, insert: bool) -> Result<Self, DbErr> {
let now = chrono::Utc::now();
if insert { if self.created_at.is_not_set() { self.created_at = Set(now); } }
self.updated_at = Set(now);
if let Set(ref mut name) = self.username { *name = name.trim().to_string(); }
Ok(self)
}
fn after_save(self, _insert: bool) -> Result<Self, DbErr> {
// 触发事件总线(示例)
// state.events.publish(Event::UserCreated{...}); // 注意:Behavior 中拿不到 state,建议在 Service 层做
Ok(self)
}
fn before_delete(self) -> Result<Self, DbErr> {
// 可做约束检查(如管理员账号禁止删除)
Ok(self)
}
}
本节聚焦 ActiveModel 的插入/局部更新、批量插入、Upsert、乐观锁、时间戳与唯一约束处理。核心要点:
Set(...)/NotSet 标记写入与跳过ActiveModelBehavior 自动填充 created_at/updated_atSea-ORM 是一款面向 async/await 的 Rust ORM,提供“Entity/Model/ActiveModel”的数据访问范式与迁移工具链。它与 Axum/Tokio 协同良好,适合在祺洛中实现稳定、可维护的数据库层。
你将学到
Sea-ORM 使用 DeriveRelation/Related 描述实体间关系,支持:
// sys_user.rs
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(belongs_to = "super::sys_dept::Entity", from = "Column::DeptId", to = "super::sys_dept::Column::Id")]
Dept,
}
impl Related<super::sys_dept::Entity> for Entity {
fn to() -> RelationDef { Relation::Dept.def() }
}