本专题将通过实现一个自动生成数据库 CRUD 的 Derive宏 来对过程宏 proc-macro
进行一步步的探讨。我们希望通过本专题的学习,能让你掌握 rust 过程宏的知识要点,并将其应用到实际开发中。
目标
- 掌握 rust 过程宏的编写
- 实现对数据模型结构体的 CRUD Derive宏
- 实现 CRUD,基于 sqlx
- 实现自定义表名、主键及是否为视图
- 实现某些字段跳过插入
- 实现某些字段跳过更新
- 实现查找单条记录的过滤条件,并可指定过滤条件是使用
ILIKE
进行模糊查询,还是使用=
进行精确匹配。 - 实现记录列表的过滤条件,并可指定过滤条件是使用
ILIKE
进行模糊查询,还是使用=
进行精确匹配。 - 实现分页
本专题使用的是 PostgreSQL 数据库,并未对其它数据库做兼容处理。
预览
最终,我们希望达到的效果是:
/// 插入
User::insert<'a>(&self, e: impl sqlx::PgExecutor<'a>) -> sqlx::Result<String>;
/// 更新
User::update<'a>(&self, e: impl sqlx::PgExecutor<'a>) -> sqlx::Result<u64>;
/// 查找单条
User::find<'a>(e: impl sqlx::PgExecutor<'a>, f:&UserFindFilter) -> sqlx::Result<Option<Self>>;
/// 列表
User::list_data<'a>(e: impl sqlx::PgExecutor<'a>, f:&UserListFilter) -> sqlx::Result<Vec<Self>>;
/// 统计
User::list_count<'a>(e: impl sqlx::PgExecutor<'a>, f:&UserListFilter) -> sqlx::Result<i64>;
/// 分页
User::list(p: &sqlx::PgPool, f:&UserListFilter) -> sqlx::Result<UserPaginate<Self>>;
/// 删除
User::list_count<'a>(e: impl sqlx::PgExecutor<'a>, id:&String) -> sqlx::Result<u64>;
以及配套的数据结构:
pub enum UserFindBy {
Id(String),
Email(String),
}
pub struct UserFindFilter {
pub by: UserFindBy,
}
pub struct UserListFilter {
pub page: u32,
pub page_size: u32,
pub email: Option<String>,
pub nickname: Option<String>,
}
pub struct UserPaginate {
pub page: u32,
pub page_size: u32,
pub total: u32,
pub total_page: u32,
pub data: Vec<User>,
}