Flutter数据库查询插件flutter_requery的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter数据库查询插件flutter_requery的使用

Flutter是一个用于开发跨平台移动应用的框架,而flutter_requery是一个用于在Flutter中进行数据获取、缓存和失效处理的库。它可以帮助开发者更方便地管理异步数据请求,并提供了诸如乐观响应、重置缓存等功能。

快速特性

  • 获取异步数据:可以轻松地从网络或其他来源获取异步数据。
  • 数据失效:能够根据需要使缓存中的数据失效。
  • 乐观响应:在实际数据更新之前先显示预期的结果,以提供更好的用户体验。
  • 重置缓存:清除所有缓存的数据而不触发界面重建。

动机

在Flutter中执行API调用通常会想到使用Dio这样的HTTP客户端。但是如何将这些API调用无缝集成到Flutter架构中呢?常见的做法是使用FutureBuilderBloc模式。然而,这两种方式都有其局限性:

  • FutureBuilder过于简单,无法在当前屏幕之外与其通信。
  • Bloc则会产生大量的样板代码,对于简单的API调用来说显得繁琐,而且也难以跨屏幕通信。

这时就可以考虑使用flutter_requery来简化这些问题。

示例

下面是一个简单的例子,展示了如何使用flutter_requery来进行数据查询:

import 'package:flutter/material.dart';
import 'package:flutter_requery/flutter_requery.dart';

void main() {
  runApp(App());
}

final List<String> data = ["Hello"];

class App extends StatelessWidget {
  Future<List<String>> _getData() async {
    await Future.delayed(Duration(seconds: 1));
    return data;
  }

  Future<void> _addString() async {
    await Future.delayed(Duration(seconds: 1));
    data.add("World");
  }

  void _onPress() async {
    // 调用API并使用相同的缓存键使查询失效
    await _addString();
    queryCache.invalidateQueries('strKey');

    // 或者如果您不想等待并且确定
    // 您的API工作正常,可以使用乐观响应。
    // _addString();
    // queryCache.setOptimistic('strKey', [...data, 'World']);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Flutter requery"),
        ),
        floatingActionButton: FloatingActionButton(
          child: Text("Add"),
          onPressed: _onPress,
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Query<List<String>>(
            'strKey',
            future: _getData,
            builder: (context, response) {
              if (response.error != null) {
                return Text('Error');
              }
              if (response.loading) {
                return CircularProgressIndicator();
              }
              return ListView(
                children: response.data.map((str) => Text(str)).toList(),
              );
            },
          ),
        ),
      ),
    );
  }
}

在这个例子中,我们定义了一个包含字符串列表的data变量作为模拟的数据源。_getData()方法模拟了一个耗时的操作(例如网络请求),然后返回这个列表。Query小部件负责发起查询,当数据准备好后通过builder函数构建UI。点击“Add”按钮时,我们会向data添加新的元素并通过queryCache.invalidateQueries使缓存失效,从而重新加载最新的数据。

使用说明

缓存键

每个查询都需要一个缓存键,它可以是字符串、整数或者由字符串和整数组成的列表。选择合适的缓存键有助于更智能地管理数据的失效。

/// 正确的方式
const k1 = 'myKey';
const k2 = 1;
const k3 = ["data", 1]

/// 错误的方式
const k1 = 1.0;
const k2 = true;
const k3 = ["data", true];

查询

一旦定义了缓存键,接下来就是编写查询逻辑。Query小部件接受三个参数:cacheKeyfuture以及builder。其中builder遵循Flutter的构造模式,接收BuildContextQueryResponse对象作为参数。

Query<List<String>>(
  'myCacheKey',
  future: ()async {
    await Future.delayed(Duration(seconds: 1));
    return ["Hello"]
  },
  builder: (context, QueryResponse response) {
    /// 处理错误状态
    if (response.error != null) {
      return Text('Error');
    }
    /// 处理加载状态
    if (response.loading) {
      return Text('Loading...');
    }
    final children = response.data.map((str) => Text(str)).toList();
    return ListView(
      children: children
    );
  },
);

数据失效

您可以选择等待API响应完成后再刷新UI,也可以立即更新缓存中的数据并重建UI树。flutter_requery提供了queryCache全局实例来帮助您实现这一点。

// 使单个查询失效
queryCache.invalidateQueries('strKey');

// 批量使多个查询失效
queryCache.invalidateQueries(['strKey1', 'strKey2']);

// 如果您的键是列表形式,则结果如下所示
queryCache.invalidateQueries([
  ['strKey', 1],
  ['strKey2', 2]
]);

// 清除所有缓存中的查询
queryCache.invalidateAll()

乐观响应

如果等待API响应的时间过长,您可以直接更新缓存数据并立即重建UI树。

queryCache.setOptimistic("requests", [...oldData, newData]);

重置

重置意味着清除所有缓存的数据但不重建UI树。这在用户登出等场景下非常有用。

queryCache.reset();

总结

API 描述
Query 用于数据获取操作的Flutter小部件。
queryCache.invalidateQueries 根据缓存键使指定的查询失效并重建UI树。
queryCache.invalidateAll 清除所有缓存中的查询并重建UI树。
queryCache.setOptimistic 手动设置缓存数据并重建UI树。
queryCache.reset 清除所有缓存中的查询但不重建UI树。

希望以上内容对您有所帮助!如果您有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter数据库查询插件flutter_requery的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据库查询插件flutter_requery的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中使用flutter_requery插件进行数据库查询时,你可以利用其强大的功能来简化数据库操作。flutter_requery是基于Requery库的一个Flutter插件,Requery是一个轻量级的关系型数据库ORM(对象关系映射)框架。以下是一个简单的示例,展示了如何在Flutter项目中使用flutter_requery进行数据库查询。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加flutter_requery的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_requery: ^最新版本号

然后运行flutter pub get来安装依赖。

2. 配置数据库模型

接下来,你需要定义你的数据库模型。例如,我们定义一个简单的User模型:

import 'package:flutter_requery/flutter_requery.dart';
import 'package:requery/requery.dart';

@Entity
abstract class User {
  @Key
  @Generated
  int get id;

  String get name;
  set name(String name);

  String get email;
  set email(String email);
}

3. 初始化数据库

在你的应用中初始化数据库连接和配置:

import 'package:flutter/material.dart';
import 'package:flutter_requery/flutter_requery.dart';
import 'package:requery/dart.dart';
import 'user_model.dart'; // 假设你的User模型在这个文件中

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Requery Example'),
        ),
        body: DatabaseScreen(),
      ),
    );
  }
}

class DatabaseScreen extends StatefulWidget {
  @override
  _DatabaseScreenState createState() => _DatabaseScreenState();
}

class _DatabaseScreenState extends State<DatabaseScreen> {
  late PersistenceProvider<User> _provider;

  @override
  void initState() {
    super.initState();
    _initDatabase();
  }

  Future<void> _initDatabase() async {
    // 初始化数据库
    var config = await PersistenceProvider.configure(
      databaseSource: Store.SQLITE,
      databaseName: 'example.db',
      models: [User],
      modules: [],
    );

    setState(() {
      _provider = config.provider;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () async {
          await _queryDatabase();
        },
        child: Text('Query Database'),
      ),
    );
  }

  Future<void> _queryDatabase() async {
    if (_provider != null) {
      var result = await _provider.select(User.classType)
        .where(User.NAME.eq('John Doe'))
        .singleOrNull();

      if (result != null) {
        print('Found user: ${result.name}, ${result.email}');
      } else {
        print('User not found');
      }
    }
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用,点击按钮来查询数据库中的用户。

注意事项

  1. 错误处理:在实际应用中,你应该添加适当的错误处理逻辑。
  2. 异步操作:数据库操作通常是异步的,因此确保你正确处理异步代码。
  3. 依赖注入:对于更复杂的应用,你可能需要使用依赖注入来管理数据库提供者的生命周期。

以上是一个基本的示例,展示了如何在Flutter中使用flutter_requery进行数据库查询。根据你的具体需求,你可以进一步扩展和自定义这个示例。

回到顶部