數據庫存儲是咱們經常使用的存儲方式之一,對大批量數據有增、刪、改、查操做需求時,咱們就會想到使用數據庫,Flutter中提供了一個sqflite插件供咱們用於大量數據執行CRUD操做。本篇咱們就來一塊兒學習sqflite的使用。算法
在pubspec.yaml文件中添加path_provider插件,最新版本爲1.0.0,以下:sql
dependencies:
flutter:
sdk: flutter
#sqflite插件
sqflite: 1.0.0
複製代碼
而後命令行執行flutter packages get
便可將插件下載到本地。數據庫
插入數據操做有兩個方法:編程
Future<int> rawInsert(String sql, [List<dynamic> arguments]);
Future<int> insert(String table, Map<String, dynamic> values,
{String nullColumnHack, ConflictAlgorithm conflictAlgorithm});
複製代碼
rawInsert
方法第一個參數爲一條插入sql語句,可使用?
做爲佔位符,經過第二個參數填充數據。bash
insert
方法第一個參數爲操做的表名,第二個參數map中是想要添加的字段名和對應字段值。微信
查詢操做一樣實現了兩個方法:async
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
方法第一個參數爲操做的表名,後邊的可選參數依次表示是否去重、查詢字段、WHERE子句(可以使用?
做爲佔位符)、WHERE子句佔位符參數值、GROUP BY子句、HAVING子句、ORDER BY子句、查詢的條數、查詢的偏移位等。ide
rawQuery
方法第一個參數爲一條查詢sql語句,可使用?
做爲佔位符,經過第二個參數填充數據。學習
修改操做一樣實現了兩個方法:ui
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
方法第一個參數爲一條更新sql語句,可使用?
做爲佔位符,經過第二個參數填充數據。
update
方法第一個參數爲操做的表名,第二個參數爲修改的字段和對應值,後邊的可選參數依次表示WHERE子句(可以使用?
做爲佔位符)、WHERE子句佔位符參數值、發生衝突時的操做算法(包括回滾、終止、忽略等等)。
修改操做一樣實現了兩個方法:
Future<int> rawDelete(String sql, [List<dynamic> arguments]);
Future<int> delete(String table, {String where, List<dynamic> whereArgs});
複製代碼
rawDelete
方法第一個參數爲一條刪除sql語句,可使用?
做爲佔位符,經過第二個參數填充數據。
delete
方法第一個參數爲操做的表名,後邊的可選參數依次表示WHERE子句(可以使用?
做爲佔位符)、WHERE子句佔位符參數值。
咱們以圖書管理系統來舉例。
首先,咱們建立一個書籍類,包括書籍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];
}
}
複製代碼
其次,咱們開始實現數據庫相關操做:
// 獲取數據庫文件的存儲路徑
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db');
//根據數據庫文件路徑和數據庫版本號建立數據庫表
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) ''');
});
複製代碼
// 插入一條書籍數據
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;
}
// 根據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;
}
// 根據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]);
}
複製代碼
數據庫對象使用完以後要在適當的時候關閉掉,可在helper類中實現如下方法。
Future close() async => db.close();
複製代碼
運行效果:
sqflite同時支持事務,經過事務能夠將多條原子操做放在一塊兒執行,保證操做要麼所有執行完成,要麼都不執行。 好比有兩條書籍數據必須所有插入書庫中才算添加成功,則使用以下方法
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咱們就能夠開發更豐富的應用程序,在開發實踐中你們遇到任何問題均可以給咱們發消息反饋,你們一塊兒交流探討共同進步。針對一些用戶的反饋咱們將在下一篇介紹Flutter的代碼調試。
說明:
文章轉載自對應的「Flutter編程指南」微信公衆號,更多Flutter相關技術文章打開微信掃描二維碼關注微信公衆號獲取。