今日的程式碼 => GITHUB
這篇將要介紹 Sqflite + Provider 的資料庫範例。
會創立一個 table
,名稱叫做 user
,儲存在應用程式目錄底下的 my.db 文件裡面,會有以下幾個欄位
新增、更新需要整筆資料的參數,刪除只需要 item 的 id 的參數,取得所有資料是一個 void 的方法,
class UserDB {
static final UserDB db = UserDB();
Database? _database;
Future<Database> get database async {
if (_database != null) {
return _database!;
}
_database = await openDb();
return _database!;
}
Future openDb() async {
// 獲取我們的應用程序目錄的位置。這是我們應用程序文件的存儲位置,並且僅存儲我們的應用程序文件。
// 當應用被刪除時,此目錄中的文件也會被刪除。
return await openDatabase(join(await getDatabasesPath(), "my.db"),
version: 1,
onOpen: (db) async {}, onCreate: (Database db, int version) async {
// Create the user table
await db.execute(
"CREATE TABLE user(id INTEGER PRIMARY KEY autoincrement,firstName TEXT,lastName TEXT,time Text)");
});
}
Future insertUserData(UserModel model) async {
final db = await database;
return db.insert('user', model.toMap());
}
Future updateUser(UserModel model) async {
final db = await database;
return db
.update('user', model.toMap(), where: "id = ?", whereArgs: [model.id]);
}
Future<int> deleteUser(int id) async {
final db = await database;
return db.delete('user', where: "id = ?", whereArgs: [id]);
}
Future<List<UserModel>> getUser() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('user');
List<UserModel> list = maps.isNotEmpty
? maps.map((note) => UserModel.fromMap(note)).toList()
: [];
return list;
}
Future close() async => db.close();
}
這邊的話就很吃 StreamController 的觀念了
StreamSink
= 事件的入口StreamController
= 即時監聽的控制器Stream
= 用於監聽,可以用 listen 來監聽StreamSubscription
= 有點類似訂閱(!?)另類的控制監聽的東西,最後再不需要的時候關閉。具備 cacenl、pauseclass AddUsersProvider extends ChangeNotifier {
/// 取得所有 user 資料的 controller
final _usersController = StreamController<List<UserModel>>.broadcast();
Stream<List<UserModel>> get getUserStream => _usersController.stream;
/// 新增的 controller
final _insertController = StreamController<UserModel>.broadcast();
/// 更新的 controller
final _updateController = StreamController<UserModel>.broadcast();
/// 刪除的 controller
final _deleteController = StreamController<int>.broadcast();
/// 搜尋的 controller
final _searchController = StreamController<String>.broadcast();
/// Sink
StreamSink<UserModel> get insert => _insertController.sink;
StreamSink<UserModel> get update => _updateController.sink;
StreamSink<int> get delete => _deleteController.sink;
StreamSink<String> get search => _searchController.sink;
/// 初始化
AddUsersProvider() {
updateScreenData();
_updateController.stream
.listen((userModel) => _handleUpdateUser(userModel));
_insertController.stream.listen((userModel) => _handleAddUser(userModel));
_deleteController.stream
.listen((userModel) => _handleDeleteUser(userModel));
_searchController.stream
.listen((userModel) => _handleSearchUser(userModel));
}
/// 新增
void _handleAddUser(UserModel userModel) async {
await UserDB.db.insertUserData(userModel);
updateScreenData();
}
/// 更新
void _handleUpdateUser(UserModel userModel) async {
await UserDB.db.updateUser(userModel);
updateScreenData();
}
/// 刪除
void _handleDeleteUser(int id) async {
await UserDB.db.deleteUser(id);
updateScreenData();
}
/// 搜尋
void _handleSearchUser(String text) async {
List<UserModel> user = await UserDB.db.getUser();
var listData = <UserModel>[];
user.forEach((stud) {
var st2 = UserModel(
id: stud.id,
lastName: stud.lastName,
firstName: stud.firstName,
time: stud.time);
if ((st2.firstName.toLowerCase() + " " + st2.lastName.toLowerCase())
.contains(text.toLowerCase()) ||
st2.firstName.toLowerCase().contains(text.toLowerCase()) ||
st2.lastName.toLowerCase().contains(text.toLowerCase()) ||
st2.time.toLowerCase().contains(text.toLowerCase())) {
listData.add(stud);
}
});
_usersController.sink.add(listData);
}
/// 取得資料
void updateScreenData() async {
List<UserModel> users = await UserDB.db.getUser();
_usersController.sink.add(users);
}
@override
void dispose() {
_usersController.close();
_insertController.close();
_deleteController.close();
_updateController.close();
_searchController.close();
UserDB.db.close();
super.dispose();
}
}
MultiProvider(
providers: [
ChangeNotifierProvider<AddUsersProvider>(
create: (context) => new AddUsersProvider(),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.cyan,
),
home: HomePage(),
),
);
context.read<AddUsersProvider>().search.add(changed)
context.read<AddUsersProvider>().delete.add(data[index].id!)
context.read<AddUsersProvider>().update.add(UserModel(
id: userModel!.id,
firstName: _firstNameController.text,
lastName: _lastNameController.text,
time: nowTime()));
context.read<AddUsersProvider>().insert.add(UserModel(
firstName: _firstNameController.text,
lastName: _lastNameController.text,
time: nowTime()));
class ShowStream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<List<UserModel>>(
stream: context.watch<AddUsersProvider>().getUserStream,
builder: (BuildContext context, AsyncSnapshot<List<UserModel>> snapshot) {
if (snapshot.hasData) {
if (snapshot.data!.length == 0) {
return Text('No Data');
}
return HomeList(data: snapshot.data!);
}
return Center(
child: CircularProgressIndicator(),
);
},
);
}
}
更詳細的程式碼請看 GITHUB