📜  在Flutter中使用 SQLite 持久化数据

📅  最后修改于: 2022-05-13 01:54:57.504000             🧑  作者: Mango

在Flutter中使用 SQLite 持久化数据

SQLite 是一个开源的计算机数据库,它不会产生一条信息,执行完全不同的操作,如添加、删除和带走知识。 SQLite 不需要服务器或后端代码,所有信息都保存在设备内的计算机文件中,或者我们会说它是本地存储的。

安装 SQLite 插件到Flutter

为了能够在Flutter中使用 SQLite,您希望使用 SQLite 插件。因此,您希望导航到 pubspec.yaml 文件来展示它,

并添加 SQLite 和路径依赖项。

Dart
dependencies:
  cupertino_icons: ^1.0.2
  flutter:
    sdk: flutter
  path: ^1.8.0
  sqflite: ^2.0.0+4


Dart
class Planets {
  late final int id;
  late final String name;
  late final int age;
  late final int distancefromsun;
  
  Planets({
    required this.id,
    required this.name,
    required this.age,
    required this.distancefromsun,
  });
   
  Planets.fromMap(Map result)
      : id = result["id"],
        name = result["name"],
        age = result["age"],
        distancefromsun = result["distancefromsun"];
  Map toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
      'distancefromsun': distancefromsun
    };
  }
}


Dart
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'model.dart';
  
class DataBase {
  Future initializedDB() async {
    String path = await getDatabasesPath();
    return openDatabase(
      join(path, 'planets.db'),
      version: 1,
      onCreate: (Database db, int version) async {
        await db.execute(
          "CREATE TABLE planets(id INTEGER PRIMARY KEY , name TEXT NOT NULL,age INTEGER NOT NULL,distancefromsun INTEGER NOT NULL)",
        );
      },
    );
  }
  
  // insert data
  Future insertPlanets(List planets) async {
    int result = 0;
    final Database db = await initializedDB();
    for (var planet in planets) {
      result = await db.insert('planets', planet.toMap(),
          conflictAlgorithm: ConflictAlgorithm.replace);
    }
  
    return result;
  }
  
  // retrieve data
  Future> retrievePlanets() async {
    final Database db = await initializedDB();
    final List> queryResult = await db.query('planets');
    return queryResult.map((e) => Planets.fromMap(e)).toList();
  }
  
  // delete user
  Future deletePlanet(int id) async {
    final db = await initializedDB();
    await db.delete(
      'planets',
      where: "id = ?",
      whereArgs: [id],
    );
  }
}


Dart
import 'package:flutter/material.dart';
import 'package:sqliteimplementation/model.dart';
import 'package:sqliteimplementation/service.dart';
  
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(Home());
}
  
class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);
  
  @override
  State createState() => _HomeState();
}
  
class _HomeState extends State {
  late DataBase handler;
  Future addPlanets() async {
    Planets firstPlanet =
        Planets(name: "Mercury", age: 24, id: 1, distancefromsun: 10);
    Planets secondPlanet =
        Planets(name: "Venus", age: 31, id: 2, distancefromsun: 20);
    Planets thirdPlanet =
        Planets(id: 3, name: 'Earth', age: 4, distancefromsun: 30);
     Planets fourthPlanet =
        Planets(id: 4, name: 'Mars', age: 5, distancefromsun: 40);
  
    List planets = [firstPlanet, secondPlanet,thirdPlanet,fourthPlanet];
    return await handler.insertPlanets(planets);
  }
  
  @override
  void initState() {
    super.initState();
    handler = DataBase();
    handler.initializedDB().whenComplete(() async {
      await addPlanets();
      setState(() {});
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder(
          future: handler.retrievePlanets(),
          builder:
              (BuildContext context, AsyncSnapshot> snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data?.length,
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    child: ListTile(
                      contentPadding: const EdgeInsets.all(8.0),
                      title: Text(snapshot.data![index].name),
                      subtitle: Text(snapshot.data![index].age.toString()),
                    ),
                  );
                },
              );
            } else {
              return const Center(child: CircularProgressIndicator());
            }
          },
        ),
      ),
    );
  }
}


现在你可以开始在Flutter项目中使用 SQLite 了!

定义行星模型

定义需要存储数据的模型类。我们的模型类具有数据成员id、name、age、distancefromsun和初始化数据成员的构造函数。

Dart

class Planets {
  late final int id;
  late final String name;
  late final int age;
  late final int distancefromsun;
  
  Planets({
    required this.id,
    required this.name,
    required this.age,
    required this.distancefromsun,
  });
   
  Planets.fromMap(Map result)
      : id = result["id"],
        name = result["name"],
        age = result["age"],
        distancefromsun = result["distancefromsun"];
  Map toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
      'distancefromsun': distancefromsun
    };
  }
}

定义数据库类

在 Database 类中我们所有的功能都在这里实现,Database 类有以下方法

  • initializedDB实际上是使用 SQLite 的getDatabasePath方法获取默认数据路径,使用 SQLite 的openDatabase方法将数据库打开到其中,然后创建表 planets。
  • insertPlanets方法获取行星列表并一一插入表中的行星。
  • retrievePlanets返回行星列表。
  • deletePlanets使用主键 id 从数据库中删除行星。

Dart

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'model.dart';
  
class DataBase {
  Future initializedDB() async {
    String path = await getDatabasesPath();
    return openDatabase(
      join(path, 'planets.db'),
      version: 1,
      onCreate: (Database db, int version) async {
        await db.execute(
          "CREATE TABLE planets(id INTEGER PRIMARY KEY , name TEXT NOT NULL,age INTEGER NOT NULL,distancefromsun INTEGER NOT NULL)",
        );
      },
    );
  }
  
  // insert data
  Future insertPlanets(List planets) async {
    int result = 0;
    final Database db = await initializedDB();
    for (var planet in planets) {
      result = await db.insert('planets', planet.toMap(),
          conflictAlgorithm: ConflictAlgorithm.replace);
    }
  
    return result;
  }
  
  // retrieve data
  Future> retrievePlanets() async {
    final Database db = await initializedDB();
    final List> queryResult = await db.query('planets');
    return queryResult.map((e) => Planets.fromMap(e)).toList();
  }
  
  // delete user
  Future deletePlanet(int id) async {
    final db = await initializedDB();
    await db.delete(
      'planets',
      where: "id = ?",
      whereArgs: [id],
    );
  }
}

定义主文件

  • 在 main 文件中,我们实际上调用了main函数并运行了 runApp。
  • initState 方法添加数据并调用insertPlanets方法。
  • 然后我们简单地在用户屏幕上显示数据。

Dart

import 'package:flutter/material.dart';
import 'package:sqliteimplementation/model.dart';
import 'package:sqliteimplementation/service.dart';
  
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(Home());
}
  
class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);
  
  @override
  State createState() => _HomeState();
}
  
class _HomeState extends State {
  late DataBase handler;
  Future addPlanets() async {
    Planets firstPlanet =
        Planets(name: "Mercury", age: 24, id: 1, distancefromsun: 10);
    Planets secondPlanet =
        Planets(name: "Venus", age: 31, id: 2, distancefromsun: 20);
    Planets thirdPlanet =
        Planets(id: 3, name: 'Earth', age: 4, distancefromsun: 30);
     Planets fourthPlanet =
        Planets(id: 4, name: 'Mars', age: 5, distancefromsun: 40);
  
    List planets = [firstPlanet, secondPlanet,thirdPlanet,fourthPlanet];
    return await handler.insertPlanets(planets);
  }
  
  @override
  void initState() {
    super.initState();
    handler = DataBase();
    handler.initializedDB().whenComplete(() async {
      await addPlanets();
      setState(() {});
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder(
          future: handler.retrievePlanets(),
          builder:
              (BuildContext context, AsyncSnapshot> snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data?.length,
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    child: ListTile(
                      contentPadding: const EdgeInsets.all(8.0),
                      title: Text(snapshot.data![index].name),
                      subtitle: Text(snapshot.data![index].age.toString()),
                    ),
                  );
                },
              );
            } else {
              return const Center(child: CircularProgressIndicator());
            }
          },
        ),
      ),
    );
  }
}

输出:

输出