Flutter本地数据库管理插件in_app_database的使用
Flutter本地数据库管理插件in_app_database的使用
初始化
在使用InAppDatabase
之前,我们需要进行初始化。以下是一个简单的初始化示例:
final _kLimitations = {
"users": const InAppWriteLimitation(5),
"posts": const InAppWriteLimitation(10),
"users/user_id/posts": const InAppWriteLimitation(10),
};
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final db = await SharedPreferences.getInstance();
// Map<String, dynamic> db = {};
InAppDatabase.init(
limiter: (key) async {
return _kLimitations[key]; // 可选参数
},
reader: (String key) async {
return db.getString(key);
// final x = db[key];
// return x;
},
writer: (String key, String? value) async {
if (value != null) {
return db.setString(key, value);
// db[key] = value;
// return true;
} else {
return db.remove(key);
// db.remove(key);
// return true;
}
},
);
runApp(const MyApp());
}
使用场景
添加集合文档
添加一个新的用户到集合中:
Future<InAppDocumentSnapshot?> addCollectionDocument() {
return InAppDatabase.i.collection("users").add({
"username": UserFaker.username,
"email": UserFaker.email,
"age": UserFaker.age,
"country": UserFaker.country,
"photoUrl": UserFaker.photoUrl,
});
}
设置新文档
设置一个特定的文档:
Future<InAppDocumentSnapshot?> setDocument() {
return InAppDatabase.i.collection("users").doc("1").set({
"username": "This is a username",
"email": "This is a user email",
"age": 24,
"country": "Bangladesh",
"photoUrl": "null",
"hobbies": ['coding', 'gaming', 'sleeping'],
"skills": ['flutter', 'android', 'node.js', 'spring boot', 'etc'],
});
}
更新特定文档
更新特定用户的文档:
Future<InAppDocumentSnapshot?> updateSpecificDocument() {
return InAppDatabase.i.collection("users").doc("1").update({
'username': "This is a updated username",
'email': "This is a updated user email",
'age': InAppFieldValue.increment(2),
'balance': InAppFieldValue.increment(-10.2),
'hobbies': InAppFieldValue.arrayUnion(['swimming']),
'skills': InAppFieldValue.arrayRemove(['node.js', 'spring boot']),
'timestamp': InAppFieldValue.serverTimestamp(),
'photoUrl': InAppFieldValue.delete(),
});
}
删除特定文档
删除特定用户的文档:
Future<bool> deleteSpecificDocument() {
return InAppDatabase.i.collection("users").doc("1").delete();
}
获取特定文档
获取特定用户的文档:
Future<InAppDocumentSnapshot?> getSpecificDocument() {
return InAppDatabase.i.collection("users").doc("1").get();
}
获取所有文档
获取集合中的所有文档:
Future<InAppQuerySnapshot> getAllDocuments() {
return InAppDatabase.i.collection("users").get();
}
获取特定文档(简单查询)
通过用户名获取特定用户的文档:
Future<InAppQuerySnapshot> getSpecificDocumentsByQuery() {
return InAppDatabase.i
.collection("users")
.where("username", isEqualTo: "emma_smith")
.get();
}
获取特定文档(复杂查询)
通过多个条件获取特定用户的文档:
Future<InAppQuerySnapshot> getSpecificDocumentsByQuery() {
return InAppDatabase.i
.collection("users")
.where(InAppFilter.or([
InAppFilter("username", isEqualTo: "emma_smith"),
InAppFilter("age", isGreaterThanOrEqualTo: 50),
]))
.where("age", isLessThanOrEqualTo: 60)
.orderBy("age", descending: false)
.orderBy("email", descending: false)
.limit(10)
.get();
}
获取所有文档(流)
通过流获取集合中的所有文档:
Stream<InAppQuerySnapshot> getCollectionSnapshots() {
return InAppDatabase.i.collection("users").snapshots();
}
获取特定文档(简单查询)(流)
通过流获取特定用户的文档:
Stream<InAppQuerySnapshot> getSpecificDocumentsByQuerySnapshots() {
return InAppDatabase.i
.collection("users")
.where("username", isEqualTo: "emma_smith")
.snapshots();
}
获取特定文档(复杂查询)(流)
通过流获取特定用户的文档:
Stream<InAppQuerySnapshot> getComplexQuerySnapshots() {
return InAppDatabase.i
.collection("users")
.where(InAppFilter.or([
InAppFilter("username", isEqualTo: "emma_smith"),
InAppFilter("age", isGreaterThanOrEqualTo: 50),
]))
.where("age", isLessThanOrEqualTo: 60)
.orderBy("age", descending: false)
.orderBy("email", descending: false)
.limit(10)
.snapshots();
}
完整示例代码
以下是完整的示例代码,展示了如何使用InAppDatabase
插件:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:in_app_database/in_app_database.dart';
import 'package:in_app_faker/in_app_faker.dart';
import 'package:shared_preferences/shared_preferences.dart';
final _kLimitations = {
"users": const InAppWriteLimitation(5),
"posts": const InAppWriteLimitation(10),
"users/user_id/posts": const InAppWriteLimitation(10),
};
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final db = await SharedPreferences.getInstance();
// Map<String, dynamic> db = {};
InAppDatabase.init(
limiter: (key) async {
return _kLimitations[key]; // 可选参数
},
reader: (String key) async {
return db.getString(key);
// return db[key];
},
writer: (String key, String? value) async {
if (value != null) {
return db.setString(key, value);
// db[key] = value;
// return true;
} else {
return db.remove(key);
// db.remove(key);
// return true;
}
},
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'In App Database',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const Home(),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
[@override](/user/override)
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("In App Database"),
centerTitle: true,
),
body: SafeArea(
child: SizedBox(
width: double.infinity,
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Counter Snapshot",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
StreamBuilder(
stream: InAppDatabase.i.collection("users").count().snapshots(),
builder: (context, s) {
final count = s.data?.count ?? 0;
return Text("Total users: $count");
},
),
const SizedBox(height: 24),
const Text(
"Document Snapshot",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
StreamBuilder(
stream: InAppDatabase.i.collection("users").doc("1").snapshots(),
builder: (context, s) {
final item = s.data?.data ?? {};
return ListTile(
leading: CircleAvatar(
child: Text("${item["age"]}"),
),
title: Text("${item["username"]}"),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("${item["email"]}"),
Text(
"Updated At: ${item["updateAt"] ?? "Not update yet"}",
maxLines: 1,
),
],
),
);
},
),
const SizedBox(height: 24),
const Text(
"Collection Snapshots",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
StreamBuilder(
stream: InAppDatabase.i.collection("users").snapshots(),
builder: (context, s) {
final data = s.data?.docs ?? [];
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
final item = data.elementAt(index).data;
return ListTile(
leading: CircleAvatar(
child: Text("${item?["age"]}"),
),
title: Text("${item?["username"]}"),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("${item?["email"]}"),
Text(
"Updated At: ${item?["updateAt"] ?? "Not update yet"}",
maxLines: 1,
),
],
),
);
},
);
},
),
],
),
),
),
),
floatingActionButton: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Button(
text: "Add",
onClick: () => InAppDatabase.i.collection("users").add({
"username": UserFaker.username,
"email": UserFaker.email,
"age": UserFaker.age,
"country": UserFaker.country,
"photoUrl": UserFaker.photoUrl,
}),
),
Button(
text: "Set",
onClick: () {
InAppDatabase.i.collection("users").doc("1").set({
"username": UserFaker.username,
"email": UserFaker.email,
"age": UserFaker.age,
"country": UserFaker.country,
"photoUrl": UserFaker.photoUrl,
});
},
),
Button(
text: "Update",
onClick: () {
InAppDatabase.i.collection("users").doc("1").update({
"updateAt": DateTime.now().millisecondsSinceEpoch.toString(),
});
},
),
Button(
text: "Delete",
onClick: () {
InAppDatabase.i.collection("users").doc("1").delete();
},
),
Button(
text: "Get",
onClick: () {
InAppDatabase.i.collection("users").doc("1").get().then((value) {
DataBottomSheet.show(
context,
title: "Get",
contents: [value],
);
});
},
),
Button(
text: "Gets",
onClick: () {
InAppDatabase.i.collection("users").get().then((value) {
if (value.exists) {
DataBottomSheet.show(
context,
title: "Gets",
contents: value.docs,
);
}
});
},
),
Button(
text: "Query",
onClick: () {
InAppDatabase.i
.collection("users")
.where("username", isEqualTo: "emma_smith")
.get()
.then((value) {
if (value.exists) {
DataBottomSheet.show(
context,
title: "Query",
contents: value.docs,
);
}
});
},
),
Button(
text: "Filter",
onClick: () {
InAppDatabase.i
.collection("users")
.where(InAppFilter.or([
InAppFilter("username", isEqualTo: "emma_smith"),
InAppFilter("age", isGreaterThanOrEqualTo: 50),
]))
.where("age", isLessThanOrEqualTo: 60)
.orderBy("age", descending: false)
.orderBy("email", descending: false)
.limit(10)
.get()
.then((value) {
if (value.exists) {
DataBottomSheet.show(
context,
title: "Filter",
contents: value.docs,
);
}
});
},
),
],
),
);
}
}
class Button extends StatelessWidget {
final String text;
final VoidCallback onClick;
const Button({
super.key,
required this.text,
required this.onClick,
});
[@override](/user/override)
Widget build(BuildContext context) {
final primary = Theme.of(context).primaryColor;
return ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: primary),
onPressed: onClick,
child: Text(text, style: const TextStyle(color: Colors.white)),
);
}
}
class DataBottomSheet extends StatefulWidget {
final String title;
final List<InAppDocumentSnapshot> contents;
const DataBottomSheet({
super.key,
required this.title,
required this.contents,
});
[@override](/user/override)
State<DataBottomSheet> createState() => _DataBottomSheetState();
static Future<T?> show<T>(
BuildContext context, {
required String title,
required List<InAppDocumentSnapshot> contents,
}) {
return showModalBottomSheet(
context: context,
builder: (context) {
return DataBottomSheet(title: title, contents: contents);
},
);
}
}
class _DataBottomSheetState extends State<DataBottomSheet> {
[@override](/user/override)
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 600,
child: Column(
children: [
Container(
width: 50,
height: 8,
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey.withAlpha(50),
borderRadius: BorderRadius.circular(25),
),
),
Text(
widget.title,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
const SizedBox(height: 16),
Expanded(
child: ListView.builder(
itemCount: widget.contents.length,
itemBuilder: (context, index) {
final item = widget.contents.elementAtOrNull(index)?.data;
return ListTile(
leading: CircleAvatar(
child: Text("${item?["age"]}"),
),
title: Text("${item?["username"]}"),
subtitle: Text("${item?["email"]}"),
);
},
),
),
],
),
);
}
}
更多关于Flutter本地数据库管理插件in_app_database的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter本地数据库管理插件in_app_database的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter本地数据库管理插件in_app_database
的代码示例。这个示例将展示如何初始化数据库、创建表、插入数据、查询数据以及更新数据。
首先,确保你已经在pubspec.yaml
文件中添加了in_app_database
依赖:
dependencies:
flutter:
sdk: flutter
in_app_database: ^x.y.z # 请将x.y.z替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是完整的代码示例:
import 'package:flutter/material.dart';
import 'package:in_app_database/in_app_database.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('In-App Database Example'),
),
body: DatabaseExample(),
),
);
}
}
class DatabaseExample extends StatefulWidget {
@override
_DatabaseExampleState createState() => _DatabaseExampleState();
}
class _DatabaseExampleState extends State<DatabaseExample> {
late InAppDatabase _db;
@override
void initState() {
super.initState();
initDatabase();
}
Future<void> initDatabase() async {
_db = await InAppDatabase.openDatabase(
version: 1,
onCreate: (Database db, int version) async {
await db.execute(
'CREATE TABLE user ('
'id INTEGER PRIMARY KEY AUTOINCREMENT,'
'name TEXT NOT NULL,'
'age INTEGER NOT NULL'
')',
);
},
onUpgrade: (Database db, int oldVersion, int newVersion) async {
await db.execute('DROP TABLE IF EXISTS user');
onCreate(db, newVersion);
},
);
}
Future<void> insertUser(String name, int age) async {
await _db.insert(
'user',
{'name': name, 'age': age},
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<Map<String, Object>>> queryUsers() async {
return await _db.query('user');
}
Future<void> updateUser(int id, String newName, int newAge) async {
await _db.update(
'user',
{'name': newName, 'age': newAge},
where: 'id = ?',
whereArgs: [id],
);
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () async {
await insertUser('Alice', 30);
setState(() {}); // 触发UI更新(如果有UI显示数据)
},
child: Text('Insert User'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
List<Map<String, Object>> users = await queryUsers();
print('Users: $users');
// 可以在这里更新UI来显示用户列表
},
child: Text('Query Users'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
await updateUser(1, 'Bob', 35);
setState(() {}); // 触发UI更新(如果有UI显示数据)
},
child: Text('Update User'),
),
],
),
);
}
@override
void dispose() {
_db.close();
super.dispose();
}
}
解释
- 依赖管理:在
pubspec.yaml
中添加in_app_database
依赖。 - 初始化数据库:在
initDatabase
方法中,使用InAppDatabase.openDatabase
初始化数据库,并定义onCreate
和onUpgrade
方法来创建表和升级数据库结构。 - 插入数据:
insertUser
方法使用_db.insert
将数据插入到user
表中。 - 查询数据:
queryUsers
方法使用_db.query
从user
表中查询所有数据。 - 更新数据:
updateUser
方法使用_db.update
更新指定ID的用户信息。 - UI交互:使用
ElevatedButton
创建按钮,并在按钮点击事件中调用数据库操作方法。
请注意,这个示例中没有实现实际的UI更新来显示数据库中的数据,你可以根据需要在queryUsers
方法调用后更新UI组件来显示用户列表。