当前位置: 首页 > 知识库问答 >
问题:

如何在flutter中实现sqflite的惰性加载

农鸿达
2023-03-14

我是新来的。我想为我的flutter应用程序实现惰性加载功能,它使用sqflite数据库存储数据。在我的数据库中有1000+行。当应用程序打开时,我想加载10个项目。当我达到第10个数据时,然后加载下一个10个,以此类推。如何实现此功能??

import 'package:employee_list/models/emp.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';



class DatabaseHelper {

  static final _databaseName = "empdb.db";
  static final _databaseVersion = 1;

  static final table = 'cars_table';

  static final colId = 'id';
  static final colName = 'name';
  static final colAge = 'age';
  static final colPath = 'path';

  // make this a singleton class
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  // only have a single app-wide reference to the database
  static Database _database;
  Future<Database> get database async {
    if (_database != null) return _database;
    // lazily instantiate the db the first time it is accessed
    _database = await _initDatabase();
    return _database;
  }

  // this opens the database (and creates it if it doesn't exist)
  _initDatabase() async {
    String path = join(await getDatabasesPath(), _databaseName);
    return await openDatabase(path,
        version: _databaseVersion,
        onCreate: _onCreate);
  }

  // SQL code to create the database table
  Future _onCreate(Database db, int version) async {
    await db.execute('''
          CREATE TABLE $table (
            $colId INTEGER PRIMARY KEY AUTOINCREMENT,
            $colName TEXT NOT NULL,
            $colAge TEXT NOT NULL,
            $colPath TEXT NOT NULL
          )
          ''');
  }

  // Helper methods

  // Inserts a row in the database where each key in the Map is a column name
  // and the value is the column value. The return value is the id of the
  // inserted row.
  Future<int> insertEmp(Emp emp) async {
    Database db = await instance.database;
    return await db.insert(table, {'name': emp.name, 'age': emp.age, 'path': emp.path});
  }

  // All of the rows are returned as a list of maps, where each map is
  // a key-value list of columns.
  Future<List<Map<String, dynamic>>> queryAllRows() async {
    Database db = await instance.database;
    return await db.query(table);
  }

  // Queries rows based on the argument received
  Future<List<Map<String, dynamic>>> queryRows(name) async {
    Database db = await instance.database;
    return await db.query(table, where: "$colName LIKE '%$name%'");
  }

  // All of the methods (insert, query, update, delete) can also be done using
  // raw SQL commands. This method uses a raw query to give the row count.
  Future<int> queryRowCount() async {
    Database db = await instance.database;
    return Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM $table'));
  }

  // We are assuming here that the id column in the map is set. The other
  // column values will be used to update the row.
  Future<int> updateEmp(Emp emp) async {
    Database db = await instance.database;
    int id = emp.toMap()['id'];
    return await db.update(table, emp.toMap(), where: '$colId = ?', whereArgs: [id]);
  }

  // Deletes the row specified by the id. The number of affected rows is
  // returned. This should be 1 as long as the row exists.
  Future<int> deleteEmp(int id) async {
    Database db = await instance.database;
    return await db.delete('DELETE FROM $table');
  }
}
import 'package:employee_list/helper/database_helper.dart';
import 'package:employee_list/second_screen.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:io' as Io;
import 'dart:convert';

import 'models/emp.dart';




class firstScreen extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _firstScreen();
  }
}

class _firstScreen extends State<firstScreen>{

  final dbHelper = DatabaseHelper.instance;
  List<Emp> empList;
  int count = 0;


  @override
  Widget build(BuildContext context) {

    if (empList == null){
      empList = List<Emp>();
      updateListView();
    }

    return Scaffold(
      appBar: AppBar(
        title: Text('Employee List'),
          actions: <Widget>[
      Container(
      padding: EdgeInsets.only(right: 10.0),
      child: IconButton(
        icon: Icon(Icons.refresh),
        onPressed: () async {
          updateListView();
        },
      ),
     ),
          ]
      ),
      body:getListView(),

      floatingActionButton: FloatingActionButton(
        tooltip: 'Add New Employee',
        child: Icon(Icons.add),
        onPressed: () {
          debugPrint('add pressed');
          Navigator.push(context, MaterialPageRoute(builder:( context){
            return secondScreeen();
            updateListView();
          }));
        },
      ),
    );

  }


 ListView getListView(){

    return ListView.builder(
        itemCount: empList.length,
        itemBuilder: (BuildContext context, int position){
          final _byteImage = Base64Decoder().convert(this.empList[position].path);
          return Card(
            color: Colors.white,
            elevation: 2.0,
            child: ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.white,
                child:  new Image.memory(_byteImage,fit: BoxFit.fill,),
                //Icon(Icons.account_circle_outlined),
              ),
              title: Text(this.empList[position].name ,),
              subtitle: Text(this.empList[position].age,),
            ),
          );
        }
    );
  }

  void updateListView() async{
      final allRows = await dbHelper.queryAllRows();
      empList.clear();
      allRows.forEach((row) => empList.add(Emp.fromMap(row)));
      //_showMessageInScaffold('Query done.');
      setState(() {});
    }

}

共有1个答案

林魁
2023-03-14

您应该为query方法定义limit(10个实体)和offset(current page*limit):

return database.query(
  table,
  limit: limit,
  offset: page * limit
);

此外,存储当前页,并在加载新数据时增加它。您可以在此项目的historythreads方法中找到完整的示例。

 类似资料:
  • 问题内容: 好吧,我的疑问很简单:为了获得最佳性能,建议在我不需要使用的属性中始终使用惰性初始化(这很明显)。因此,请想象以下类: 在我的主类中,我将未初始化的具有“ type”属性的人称为“波纹管”: 因此,我从数据库中获得了一个简单的Person对象,并在控制台上打印了person类型。在这一刻,代理CGLIB可以发挥作用,并且可以发挥作用,一切正常。 但是,我在这里提出我的问题: 1-当我请

  • 在标记为重复之前,请考虑我已经翻阅了许多相关的堆栈溢出帖子,以及网站和文章。我还没有找到解决办法。 这个问题是Selenium Webdriver找不到XPATH的后续问题,尽管字符串看起来完全相同。通过更新代码以更优雅的方式工作,我确定问题实际上不是来自xpath方法: 这适用于前5ish元素。但是之后它会超时,通过获取img_div的内部html并打印它,我发现对于超时的元素,不是我想要的图像

  • [错误:flutter/lib/ui/ui_dart_state.cc(157)]未处理的异常:nosuchmethoderror:在null上调用了方法“to map”。E/Flutter(2893):接收器:null E/Flutter(2893):尝试调用:toMap() 我已经创建了数据库和insert操作,但是当我调用insert操作时,它给出了一个错误,即InsertNote方法是在N

  • 问题内容: 我试图在Flutter中将列表插入到sql数据库中,但是我不知道该怎么办,有人可以帮助我吗? 当我初始化mi数据库时,我有这个: 我有这个要插入数据: 但是当y尝试插入这样的值时: 我收到这样的错误: 发生异常。 SqfliteDatabaseException(DatabaseException(java.lang.String无法转换为java.lang.Integer)sql’I

  • 我已经阅读了许多关于如何在Flutter中实现Sqflite的教程和示例。每一个其他示例都只使用一个模型或数据库表。如这些教程中所定义的: https://pub.dartlang.org/packages/sqflite https://www.developerlibs.com/2018/07/flutter-sqlite-database-example.html