Flutter持久化存储之数据库存储(sqflite)详解
前言
数据库存储是我们常用的存储方式之一,对大批量数据有增、删、改、查操作需求时,我们就会想到使用数据库,flutter中提供了一个sqflite插件供我们用于大量数据执行crud操作。本篇我们就来一起学习sqflite的使用。
sqflite是一款轻量级的关系型数据库,类似sqlite。
在flutter平台我们使用sqflite库来同时支持android 和ios。
sqflite使用
引入插件
在pubspec.yaml文件中添加path_provider插件,最新版本为1.0.0,如下:
dependencies: flutter: sdk: flutter #sqflite插件 sqflite: 1.0.0
然后命令行执行flutter packages get即可将插件下载到本地。
数据库操作方法介绍
1. 插入操作
插入数据操作有两个方法:
future<int> rawinsert(string sql, [list<dynamic> arguments]); future<int> insert(string table, map<string, dynamic> values, {string nullcolumnhack, conflictalgorithm conflictalgorithm});
rawinsert方法第一个参数为一条插入sql语句,可以使用?作为占位符,通过第二个参数填充数据。
insert方法第一个参数为操作的表名,第二个参数map中是想要添加的字段名和对应字段值。
2. 查询操作
查询操作同样实现了两个方法:
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子句、查询的条数、查询的偏移位等。
rawquery方法第一个参数为一条查询sql语句,可以使用?作为占位符,通过第二个参数填充数据。
3. 修改操作
修改操作同样实现了两个方法:
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子句占位符参数值、发生冲突时的操作算法(包括回滚、终止、忽略等等)。
4. 删除操作
修改操作同样实现了两个方法:
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]; } }
其次,我们开始实现数据库相关操作:
1. 创建数据库文件和对应的表
// 获取数据库文件的存储路径 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) '''); });
2. crud操作实现
// 插入一条书籍数据 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]); }
3. 关闭数据库
数据库对象使用完之后要在适当的时候关闭掉,可在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的代码调试。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
下一篇: 郭络罗氏:受皇帝厌恶,死后还要被挫骨扬灰