在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
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
定义主文件
- 在 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());
}
},
),
),
);
}
}
输出: