关联关系
大约 2 分钟
关联关系
Sea-ORM 使用 DeriveRelation
/Related
描述实体间关系,支持:
- 一对多(has_many)
- 多对一(belongs_to)
- 多对多(many_to_many,经由中间表)
多对一(User 属于 Dept)
// 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() }
}
查询关联:
// 从用户到部门
let with_dept = entity::sys_user::Entity::find()
.find_also_related(entity::sys_dept::Entity)
.all(&db).await?; // Vec<(User, Option<Dept>)>
一对多(Dept 拥有 Users)
// sys_dept.rs
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::sys_user::Entity")]
User,
}
impl Related<super::sys_user::Entity> for Entity {
fn to() -> RelationDef { Relation::User.def() }
}
查询:
let dept = entity::sys_dept::Entity::find_by_id(1001).one(&db).await?.unwrap();
let users = dept.find_related(entity::sys_user::Entity).all(&db).await?;
多对多(User 与 Role,经 user_role)
中间表 user_role(user_id, role_id)。
// sys_user.rs
impl Related<super::sys_role::Entity> for Entity {
fn to() -> RelationDef { super::sys_user_role::Relation::Role.def() }
fn via() -> Option<RelationDef> { Some(super::sys_user_role::Relation::User.def().rev()) }
}
// sys_role.rs
impl Related<super::sys_user::Entity> for Entity {
fn to() -> RelationDef { super::sys_user_role::Relation::User.def() }
fn via() -> Option<RelationDef> { Some(super::sys_user_role::Relation::Role.def().rev()) }
}
// sys_user_role.rs
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(belongs_to = "super::sys_user::Entity", from = "Column::UserId", to = "super::sys_user::Column::Id")]
User,
#[sea_orm(belongs_to = "super::sys_role::Entity", from = "Column::RoleId", to = "super::sys_role::Column::Id")]
Role,
}
查询:
// 用户的角色
let roles = entity::sys_user::Entity::find_by_id(uid)
.find_related(entity::sys_role::Entity)
.all(&db).await?;
// 角色的用户
let users = entity::sys_role::Entity::find_by_id(rid)
.find_related(entity::sys_user::Entity)
.all(&db).await?;
自定义 JOIN
当关系复杂或需附带聚合字段,可手写 JOIN:
use sea_orm::{QuerySelect, QueryFilter, ColumnTrait, JoinType};
let rows = entity::sys_user::Entity::find()
.join(JoinType::LeftJoin, entity::sys_user::Relation::Dept.def())
.filter(entity::sys_user::Column::Status.eq(1))
.all(&db).await?;
关系约束与索引建议
- 外键约束:user.dept_id -> dept.id(维护数据一致性)
- 中间表唯一:UNIQUE(user_id, role_id)
- 常用查询字段加索引(dept_id、status 等)