Flutter持久化存儲(chǔ)之?dāng)?shù)據(jù)庫(kù)存儲(chǔ)(sqflite)詳解
前言
數(shù)據(jù)庫(kù)存儲(chǔ)是我們常用的存儲(chǔ)方式之一,對(duì)大批量數(shù)據(jù)有增、刪、改、查操作需求時(shí),我們就會(huì)想到使用數(shù)據(jù)庫(kù),F(xiàn)lutter中提供了一個(gè)sqflite插件供我們用于大量數(shù)據(jù)執(zhí)行CRUD操作。本篇我們就來(lái)一起學(xué)習(xí)sqflite的使用。
sqflite是一款輕量級(jí)的關(guān)系型數(shù)據(jù)庫(kù),類似SQLite。
在Flutter平臺(tái)我們使用sqflite庫(kù)來(lái)同時(shí)支持Android 和iOS。
sqflite使用
引入插件
在pubspec.yaml文件中添加path_provider插件,最新版本為1.0.0,如下:
dependencies: flutter: sdk: flutter #sqflite插件 sqflite: 1.0.0
然后命令行執(zhí)行flutter packages get即可將插件下載到本地。
數(shù)據(jù)庫(kù)操作方法介紹
1. 插入操作
插入數(shù)據(jù)操作有兩個(gè)方法:
Future<int> rawInsert(String sql, [List<dynamic> arguments]);
Future<int> insert(String table, Map<String, dynamic> values,
{String nullColumnHack, ConflictAlgorithm conflictAlgorithm});
rawInsert方法第一個(gè)參數(shù)為一條插入sql語(yǔ)句,可以使用?作為占位符,通過第二個(gè)參數(shù)填充數(shù)據(jù)。
insert方法第一個(gè)參數(shù)為操作的表名,第二個(gè)參數(shù)map中是想要添加的字段名和對(duì)應(yīng)字段值。
2. 查詢操作
查詢操作同樣實(shí)現(xiàn)了兩個(gè)方法:
Future<List<Map<String, dynamic>>> query(String table,
{bool distinct,
List<String> columns,
String where,
List<dynamic> whereArgs,
String groupBy,
String having,
String orderBy,
int limit,
int offset});
Future<List<Map<String, dynamic>>> rawQuery(String sql,
[List<dynamic> arguments]);
query方法第一個(gè)參數(shù)為操作的表名,后邊的可選參數(shù)依次表示是否去重、查詢字段、WHERE子句(可使用?作為占位符)、WHERE子句占位符參數(shù)值、GROUP BY子句、HAVING子句、ORDER BY子句、查詢的條數(shù)、查詢的偏移位等。
rawQuery方法第一個(gè)參數(shù)為一條查詢sql語(yǔ)句,可以使用?作為占位符,通過第二個(gè)參數(shù)填充數(shù)據(jù)。
3. 修改操作
修改操作同樣實(shí)現(xiàn)了兩個(gè)方法:
Future<int> rawUpdate(String sql, [List<dynamic> arguments]);
Future<int> update(String table, Map<String, dynamic> values,
{String where,
List<dynamic> whereArgs,
ConflictAlgorithm conflictAlgorithm});
rawUpdate方法第一個(gè)參數(shù)為一條更新sql語(yǔ)句,可以使用?作為占位符,通過第二個(gè)參數(shù)填充數(shù)據(jù)。
update方法第一個(gè)參數(shù)為操作的表名,第二個(gè)參數(shù)為修改的字段和對(duì)應(yīng)值,后邊的可選參數(shù)依次表示W(wǎng)HERE子句(可使用?作為占位符)、WHERE子句占位符參數(shù)值、發(fā)生沖突時(shí)的操作算法(包括回滾、終止、忽略等等)。
4. 刪除操作
修改操作同樣實(shí)現(xiàn)了兩個(gè)方法:
Future<int> rawDelete(String sql, [List<dynamic> arguments]);
Future<int> delete(String table, {String where, List<dynamic> whereArgs});
rawDelete方法第一個(gè)參數(shù)為一條刪除sql語(yǔ)句,可以使用?作為占位符,通過第二個(gè)參數(shù)填充數(shù)據(jù)。
delete方法第一個(gè)參數(shù)為操作的表名,后邊的可選參數(shù)依次表示W(wǎng)HERE子句(可使用?作為占位符)、WHERE子句占位符參數(shù)值。
舉個(gè)栗子
我們以圖書管理系統(tǒng)來(lái)舉例。
首先,我們創(chuàng)建一個(gè)書籍類,包括書籍ID、書名、作者、價(jià)格、出版社等信息。
final String tableBook = 'book';
final String columnId = '_id';
final String columnName = 'name';
final String columnAuthor = 'author';
final String columnPrice = 'price';
final String columnPublishingHouse = 'publishingHouse';
class Book {
int id;
String name;
String author;
double price;
String publishingHouse;
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
columnName: name,
columnAuthor: author,
columnPrice: price,
columnPublishingHouse: publishingHouse
};
if (id != null) {
map[columnId] = id;
}
return map;
}
Book();
Book.fromMap(Map<String, dynamic> map) {
id = map[columnId];
name = map[columnName];
author = map[columnAuthor];
price = map[columnPrice];
publishingHouse = map[columnPublishingHouse];
}
}
其次,我們開始實(shí)現(xiàn)數(shù)據(jù)庫(kù)相關(guān)操作:
1. 創(chuàng)建數(shù)據(jù)庫(kù)文件和對(duì)應(yīng)的表
// 獲取數(shù)據(jù)庫(kù)文件的存儲(chǔ)路徑
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db');
//根據(jù)數(shù)據(jù)庫(kù)文件路徑和數(shù)據(jù)庫(kù)版本號(hào)創(chuàng)建數(shù)據(jù)庫(kù)表
db = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
await db.execute('''
CREATE TABLE $tableBook (
$columnId INTEGER PRIMARY KEY,
$columnName TEXT,
$columnAuthor TEXT,
$columnPrice REAL,
$columnPublishingHouse TEXT)
''');
});
2. CRUD操作實(shí)現(xiàn)
// 插入一條書籍?dāng)?shù)據(jù)
Future<Book> insert(Book book) async {
book.id = await db.insert(tableBook, book.toMap());
return book;
}
// 查找所有書籍信息
Future<List<Book>> queryAll() async {
List<Map> maps = await db.query(tableBook, columns: [
columnId,
columnName,
columnAuthor,
columnPrice,
columnPublishingHouse
]);
if (maps == null || maps.length == 0) {
return null;
}
List<Book> books = [];
for (int i = 0; i < maps.length; i++) {
books.add(Book.fromMap(maps[i]));
}
return books;
}
// 根據(jù)ID查找書籍信息
Future<Book> getBook(int id) async {
List<Map> maps = await db.query(tableBook,
columns: [
columnId,
columnName,
columnAuthor,
columnPrice,
columnPublishingHouse
],
where: '$columnId = ?',
whereArgs: [id]);
if (maps.length > 0) {
return Book.fromMap(maps.first);
}
return null;
}
// 根據(jù)ID刪除書籍信息
Future<int> delete(int id) async {
return await db.delete(tableBook, where: '$columnId = ?', whereArgs: [id]);
}
// 更新書籍信息
Future<int> update(Book book) async {
return await db.update(tableBook, book.toMap(),
where: '$columnId = ?', whereArgs: [book.id]);
}
3. 關(guān)閉數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)對(duì)象使用完之后要在適當(dāng)?shù)臅r(shí)候關(guān)閉掉,可在helper類中實(shí)現(xiàn)以下方法。
Future close() async => db.close();
事務(wù)
sqflite同時(shí)支持事務(wù),通過事務(wù)可以將多條原子操作放在一起執(zhí)行,保證操作要么全部執(zhí)行完成,要么都不執(zhí)行。
比如有兩條書籍?dāng)?shù)據(jù)必須全部插入書庫(kù)中才算添加成功,則使用如下方法
Future<bool> insertTwoBook(Book book1, Book book2) async {
return await db.transaction((Transaction txn) async {
book1.id = await db.insert(tableBook, book1.toMap());
book2.id = await db.insert(tableBook, book2.toMap());
print('book1.id = ${book1.id}, book2.id = ${book2.id}');
return book1.id != null && book2.id != null;
});
}
寫在最后
以上介紹了sqflite中我們常用的幾個(gè)操作,有了sqflite我們就可以開發(fā)更豐富的應(yīng)用程序,在開發(fā)實(shí)踐中大家遇到任何問題都可以給我們發(fā)消息反饋,大家一起交流探討共同進(jìn)步。針對(duì)一些用戶的反饋我們將在下一篇介紹Flutter的代碼調(diào)試。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
sweet alert dialog 在android studio應(yīng)用問題說明詳解
這篇文章主要介紹了sweet alert dialog 在android studio應(yīng)用問題說明詳解的相關(guān)資料,本文圖文并茂介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
Android 官推 kotlin-first 的圖片加載庫(kù)——Coil的使用入門
這篇文章主要介紹了Android 官推 kotlin-first 的圖片加載庫(kù)——Coil的使用入門,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-04-04
Android實(shí)現(xiàn)界面左右滑動(dòng)切換功能
相信大家一定都使用過手機(jī)QQ和微信之類的軟件,當(dāng)我們使用時(shí)不難發(fā)現(xiàn)其界面的切換不僅可以通過點(diǎn)擊頁(yè)標(biāo)簽來(lái)實(shí)現(xiàn),還可以通過左右滑動(dòng)來(lái)實(shí)現(xiàn)的,下面小編給大家介紹下如何實(shí)現(xiàn)這個(gè)功能2016-12-12
Android數(shù)據(jù)共享 sharedPreferences 的使用方法
這篇文章主要介紹了Android數(shù)據(jù)共享 sharedPreferences 的使用方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解使用sharedpreferences,需要的朋友可以參考下2017-10-10
Android開發(fā)筆記之Android中數(shù)據(jù)的存儲(chǔ)方式(一)
這篇文章主要介紹了Android開發(fā)筆記之Android中數(shù)據(jù)的存儲(chǔ)方式(一) 的相關(guān)資料,需要的朋友可以參考下2016-01-01
Android 通過webservice上傳多張圖片到指定服務(wù)器詳解
這篇文章主要介紹了Android 通過webservice上傳多張圖片到指定服務(wù)器詳解的相關(guān)資料,需要的朋友可以參考下2017-02-02
activitygroup 切換動(dòng)畫效果如何實(shí)現(xiàn)
本文將詳細(xì)介紹activitygroup 切換動(dòng)畫效果實(shí)現(xiàn)過程,需要聊解的朋友可以參考下2012-12-12
Android系統(tǒng)view與SurfaceView的基本使用及區(qū)別分析
這篇文章主要為大家介紹了Android系統(tǒng)view與SurfaceView基本使用的案例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
Android實(shí)現(xiàn)水波紋外擴(kuò)效果的實(shí)例代碼
微信曾經(jīng)推出了一個(gè)查找附近好友的功能,大致功能是這樣的:屏幕上有一個(gè)按鈕,長(zhǎng)按按鈕的時(shí)候,會(huì)有一圈圈水波紋的動(dòng)畫向外擴(kuò)散,松手后,動(dòng)畫結(jié)束2018-05-05
Android 通過API獲取數(shù)據(jù)庫(kù)中的圖片文件方式
這篇文章主要介紹了Android 通過API獲取數(shù)據(jù)庫(kù)中的圖片文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-03-03

