< 返回版块

songday 发表于 2020-08-12 12:56

Tags:sqlx

大家好,

我在用sqlx,在查询数据库(sqlite)的时候,代码基本上都是重复的,所以我想抽象出一个专门select list的方法。

参考了sqlx代码,我整理出了:

    pub(crate) async fn sqlite_get_list<'a, D, P>(&self, query: &'a str, params: Option<Vec<P>>) -> Result<Vec<D>>
        where for<'r> D: sqlx::FromRow<'r, SqliteRow> + Send + Unpin,
              for<'q> P: Encode<'q, Sqlite> + Type<Sqlite> + Send
    {
        let mut q = sqlx::query_as::<Sqlite, D>(query);
        if let Some(params) = params {
            for p in params {
                q = q.bind(p);
            }
        }
        let r: Vec<D> = q.fetch_all(&self.sqlite).await?;
        Ok(r)
    }

然后通过下面方式调用:

datasource.sqlite_get_list::<Tag, String>("select id, name from blog_tag", None).await

上面用String,是因为sqlite_get_list需要制定两个类型,第二个是参数类型

select没有参数的时候是OK的,但是需要传参的时候,有两个问题:

  1.  let mut p: Vec<Box<dyn crate::db::SqliteParam>> = Vec::new(); // SqliteParam 是上面P的trait别名,但是dyn不让用组合的auto trait
     p.push(Box::new(0i32));
     p.push(Box::new(100i32));
     datasource.sqlite_get_list::<Tag, _>("select id, name from blog_tag", None).await
    
这个会提示`Box`不能解引用
2. `sqlite_get_list`的第二个泛型该如何指定?

我的个人想法是,参数的限定,不用照抄`sqlx`,实际上,只需要满足`usize`或`&str`就可以了

但是`Rust`的`trait`只能是并的关系

谢谢大家

评论区

写评论

还没有评论

1 共 0 条评论, 1 页