溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter持久化存儲之數(shù)據(jù)庫存儲(sqflite)詳解

發(fā)布時間:2020-10-21 01:23:24 來源:腳本之家 閱讀:1377 作者:Flutter編程指南 欄目:移動開發(fā)

前言

數(shù)據(jù)庫存儲是我們常用的存儲方式之一,對大批量數(shù)據(jù)有增、刪、改、查操作需求時,我們就會想到使用數(shù)據(jù)庫,F(xiàn)lutter中提供了一個sqflite插件供我們用于大量數(shù)據(jù)執(zhí)行CRUD操作。本篇我們就來一起學習sqflite的使用。

sqflite是一款輕量級的關(guān)系型數(shù)據(jù)庫,類似SQLite。

在Flutter平臺我們使用sqflite庫來同時支持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ù)庫操作方法介紹

1. 插入操作

插入數(shù)據(jù)操作有兩個方法:

Future<int> rawInsert(String sql, [List<dynamic> arguments]);

Future<int> insert(String table, Map<String, dynamic> values,
 {String nullColumnHack, ConflictAlgorithm conflictAlgorithm});

rawInsert方法第一個參數(shù)為一條插入sql語句,可以使用?作為占位符,通過第二個參數(shù)填充數(shù)據(jù)。

insert方法第一個參數(shù)為操作的表名,第二個參數(shù)map中是想要添加的字段名和對應字段值。

2. 查詢操作

查詢操作同樣實現(xiàn)了兩個方法:

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方法第一個參數(shù)為操作的表名,后邊的可選參數(shù)依次表示是否去重、查詢字段、WHERE子句(可使用?作為占位符)、WHERE子句占位符參數(shù)值、GROUP BY子句、HAVING子句、ORDER BY子句、查詢的條數(shù)、查詢的偏移位等。

rawQuery方法第一個參數(shù)為一條查詢sql語句,可以使用?作為占位符,通過第二個參數(shù)填充數(shù)據(jù)。

3. 修改操作

修改操作同樣實現(xiàn)了兩個方法:

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方法第一個參數(shù)為一條更新sql語句,可以使用?作為占位符,通過第二個參數(shù)填充數(shù)據(jù)。

update方法第一個參數(shù)為操作的表名,第二個參數(shù)為修改的字段和對應值,后邊的可選參數(shù)依次表示W(wǎng)HERE子句(可使用?作為占位符)、WHERE子句占位符參數(shù)值、發(fā)生沖突時的操作算法(包括回滾、終止、忽略等等)。

4. 刪除操作

修改操作同樣實現(xiàn)了兩個方法:

Future<int> rawDelete(String sql, [List<dynamic> arguments]);

Future<int> delete(String table, {String where, List<dynamic> whereArgs});

rawDelete方法第一個參數(shù)為一條刪除sql語句,可以使用?作為占位符,通過第二個參數(shù)填充數(shù)據(jù)。

delete方法第一個參數(shù)為操作的表名,后邊的可選參數(shù)依次表示W(wǎng)HERE子句(可使用?作為占位符)、WHERE子句占位符參數(shù)值。

舉個栗子

我們以圖書管理系統(tǒng)來舉例。

首先,我們創(chuàng)建一個書籍類,包括書籍ID、書名、作者、價格、出版社等信息。

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];
 }
}

其次,我們開始實現(xiàn)數(shù)據(jù)庫相關(guān)操作:

1. 創(chuàng)建數(shù)據(jù)庫文件和對應的表

// 獲取數(shù)據(jù)庫文件的存儲路徑
 var databasesPath = await getDatabasesPath();
 String path = join(databasesPath, 'demo.db');

//根據(jù)數(shù)據(jù)庫文件路徑和數(shù)據(jù)庫版本號創(chuàng)建數(shù)據(jù)庫表
 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操作實現(xiàn)

 // 插入一條書籍數(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ù)庫

數(shù)據(jù)庫對象使用完之后要在適當?shù)臅r候關(guān)閉掉,可在helper類中實現(xiàn)以下方法。

Future close() async => db.close();

事務

sqflite同時支持事務,通過事務可以將多條原子操作放在一起執(zhí)行,保證操作要么全部執(zhí)行完成,要么都不執(zhí)行。
比如有兩條書籍數(shù)據(jù)必須全部插入書庫中才算添加成功,則使用如下方法

 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中我們常用的幾個操作,有了sqflite我們就可以開發(fā)更豐富的應用程序,在開發(fā)實踐中大家遇到任何問題都可以給我們發(fā)消息反饋,大家一起交流探討共同進步。針對一些用戶的反饋我們將在下一篇介紹Flutter的代碼調(diào)試。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI