Rust的Diesel是否支持类似Hibernate@Embeddable的嵌入结构体功能?
Diesel是否支持嵌入结构体映射平表?
Diesel本身默认不自动支持嵌套结构体直接映射到数据库的平级表列,但在Diesel 2.0及以上版本,可以通过#[diesel(embed)]属性实现该需求;1.x版本则需要手动实现相关Trait。
解决方案1:Diesel 2.0+ 使用#[diesel(embed)]属性
修改你的结构体定义,在嵌套的child字段上添加#[diesel(embed)]属性,Diesel会自动将嵌套结构体的字段映射到父表对应的列中:
#[derive(Debug, Clone, Queryable, Selectable)] #[diesel(table_name = crate::schema::parents)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct Parent { id: i32, surname: String, #[diesel(embed)] child: Child, } #[derive(Debug, Clone, Queryable, Selectable)] pub struct Child { name: String, age: u8, }
此时你的schema.rs定义完全符合要求,Diesel会自动将查询结果的name、age列填充到Child结构体中,再组合为Parent实例。
解决方案2:Diesel 1.x 手动实现Trait
如果使用Diesel 1.x版本,需要手动实现Queryable和Selectable(或对应版本的Trait),手动完成列到嵌套结构体的映射:
实现Queryable
impl<'a> diesel::Queryable<'a, diesel::pg::Pg> for Parent { type Row = (i32, String, String, u8); fn build(row: Self::Row) -> Self { let (id, surname, name, age) = row; Parent { id, surname, child: Child { name, age }, } } }
实现Selectable(若需要)
impl diesel::Selectable<diesel::pg::Pg> for Parent { type Selection = ( crate::schema::parents::id, crate::schema::parents::surname, crate::schema::parents::name, crate::schema::parents::age, ); fn selection() -> Self::Selection { ( crate::schema::parents::id, crate::schema::parents::surname, crate::schema::parents::name, crate::schema::parents::age, ) } }
注意事项
- 你的
schema.rs定义是正确的,因为数据库表本身是平级结构,不存在嵌套列,所以列定义需与表结构一一对应。 - 使用
#[diesel(embed)]时,嵌套结构体的字段名必须与表中列名完全匹配,否则需要额外添加#[diesel(column_name = "xxx")]指定列名。
内容的提问来源于stack exchange,提问作者Manuelarte
相关产品推荐
相关产品推荐

