加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何存储SQLite准备好的语句供以后使用?

发布时间:2020-12-12 23:42:54 所属栏目:百科 来源:网络整理
导读:现在我的代码使用 rusqlite sqlite bindings来打开数据库连接并在我的应用程序中执行一堆数据库操作,如下所示: extern crate rusqlite;use rusqlite::SqliteConnection;struct MyAppState { db: SqliteConnection,// ... pretend there's other fields here
现在我的代码使用 rusqlite sqlite bindings来打开数据库连接并在我的应用程序中执行一堆数据库操作,如下所示:
extern crate rusqlite;

use rusqlite::SqliteConnection;

struct MyAppState {
    db: SqliteConnection,// ... pretend there's other fields here ...
}

impl MyAppState {
    fn new() -> MyAppState {
        let db = SqliteConnection::open(":memory:").unwrap();
        MyAppState {
            db: db
        }
    }

    fn query_some_info(&mut self,arg: i64) -> i64 {
        let mut stmt = self.db.prepare("SELECT ? + 1").unwrap();
        let mut result_iter = stmt.query(&[&arg]).unwrap();
        let result = result_iter.next().unwrap().unwrap().get(0);

        result
    }
}

fn main() {
    let mut app = MyAppState::new();
    for i in range(0,100) {
        let result = app.query_some_info(i);
        println!("{}",result);
    }
}

由于准备好的语句存在于局部变量中,这似乎在某种程度上忽略了准备语句的要点,因为每次调用函数并且局部变量产生时我必须重新准备它.理想情况下,我最多只准备一次所有语句,并在数据库连接期间将它们存储在MyAppState结构中.

然而,从SqliteStatement type is parameterized over the lifetime of the db connection开始,它借用了连接,并扩展了它所存在的结构,我不再对结构做任何事情,比如通过值返回struct或者调用& mut self方法(query_some_info不是真的我需要在这里采取和改变自己,但我的实际程序中的一些代码除非一切都继续存在于RefCells中,这不是最糟糕的,我猜,但仍然).

通常当借用检查员背叛我时,我的办法就是放弃堆栈纪律并放入一些Rc< RefCell< >>在这里和那里直到一切都解决了,但在这种情况下,在这两种类型中有一些生命周期,我不知道如何以一种安抚借用检查器的方式来表达它. 理想情况下,我想编写只在db打开时才准备语句的代码,或者在第一次使用它们时只准备它们一次,然后在db连接期间再也不会再调用prepare,而主要是保留rusqlite绑定的安全性,而不是针对sqlite3 C API编写代码或破坏抽象等等.我如何能?

事实上,你是对的,在Rust中兄弟参考是尴尬的.但是有一个很好的理由,它们不容易被所有权制度建模.

在这种特殊情况下,我建议你拆分结构:你可以将准备好的语句保存在专用缓存中,也可以在db的生命周期中进行参数化;例如; db应该在程序的顶部实例化并传递下来(想想依赖注入),以便依赖它的缓存可以比程序主函数更长.

这显然意味着数据库显然会被借用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读