Flutter&DartFlutter学习

哥哥手把手教你Flutter中SQFLite数据库的使用---粘

2019-07-25  本文已影响10人  哥哥是欧巴Vitory

Flutter中SQFLite数据库:

支持事务的批量操作

支持增删改查

在iOS和Android双端后台线程中执行数据库操作

使用方式:

1,添加依赖

dependencies:... sqflite: any

2,导入文件:

import 'package:sqflite/sqflite.dart';

3, //创建数据库

Future<String> _createNewDb(String dbName) async {

//获取数据库文件路径

var dbPath = await getDatabasesPath();

print('dbPath:' + dbPath);

String path = join(dbPath, dbName);

if (await new Directory(dirname(path)).exists()) {

await deleteDatabase(path);

} else {

try { await new Directory(dirname(path)).create(recursive: true);

} catch (e) { print(e);

}

}

return path;

}

_create() async {

dbPath = await _createNewDb(dbName);

Database db = await openDatabase(dbPath);

await db.execute(sql_createTable);

await db.close();

setState(() {

_result = '创建user.db成功,创建user_table成功'; });

}

//打开数据库,获取数据库对象

_open() async {

if(null == dbPath){ var path = await getDatabasesPath();

dbPath = join(path, dbName); print('dbPath:' + dbPath);

}

return await openDatabase(dbPath);

}

4,删除数据库

await deleteDatabase(path); 

5,打开数据库并创建一张表          

Database  database = await  openDatabase(path, version: 1, onCreate: (Database db, int version) async {                                                                                                                                        await db.execute( "CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)");

});   

// 插入数据库的两种方式

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

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

rawInsert方法第一个参数为一条插入sql语句,可以使用?作为占位符,通过第二个参数填充数据。                                                                                                                                              insert方法第一个参数为操作的表名,第二个参数map中是想要添加的字段名和对应字段值。 

示例:

 await database.transaction((txn) async {

 int id1 = await txn.rawInsert( 'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)');

 print("inserted1: $id1"); 

//  查询操作的两种方法

Future<List<Map<String, dynamic>>> query(String table,

 {bool distinct,

 List<String> columns,

 String where,

 List<dynamic> whereArgs,

 String groupBy,

 String having,

 String orderBy,

 intlimit,

 intoffset});

Future<List<Map<String, dynamic>>> rawQuery(String sql, [List<dynamic> arguments]); 

query方法第一个参数为操作的表名,后边的可选参数依次表示是否去重、查询字段、WHERE子句(可使用?作为占位符)、WHERE子句占位符参数值、GROUP BY子句、HAVING子句、ORDER BY子句、查询的条数、查询的偏移位等。                                                                                                                                                                                                                      rawQuery方法第一个参数为一条查询sql语句,可以使用?作为占位符,通过第二个参数填充数据。 

示例如下:

await database.transaction ((txn)  async {                                                                                                                                                                                                                                            int id1 = await txn.rawInsert( 'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)');                                                                                                                         print("inserted1: $id1");                                                                                                                                                                                                                                                                        int id2 = await txn.rawInsert( 'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)', ["another name", 12345678, 3.1416]);                                                                                       print("inserted2: $id2");}); 

//  更新的两种方式

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子句占位符参数值、发生冲突时的操作算法(包括回滚、终止、忽略等等)。

示例如下:

int count =awaitdatabase.rawUpdate(

UPDATE Test SET name = ?, VALUE = ? WHERE name = ?',["updated name","9876","some name"]);

print("updated: $count");

// 删除的两种方式

Future rawDelete(String sql, [List arguments]); 

Future delete(String table, {String where, List whereArgs}); 

rawDelete方法第一个参数为一条删除sql语句,可以使用?作为占位符,通过第二个参数填充数据。 

delete方法第一个参数为操作的表名,后边的可选参数依次表示WHERE子句(可使用?作为占位符)、WHERE子句占位符参数值。 

示例如下:

count =awaitdatabase.rawDelete('DELETE FROM Test WHERE name = ?',['an

other name']);

assert(count==1);

// 获取Test表的数据

List list = awaitdatabase.rawQuery('SELECT * FROM Test');List expectedList=[{"name":"updated name","id":1,"value":9876,"num":456.789},{"name":"another name","id":2,"value":12345678,"num":3.1416}];

print(list);

print(expectedList);

assert(constDeepCollectionEquality().equals(list, expectedList));

// 获取记录的数量

count = Sqflite.firstIntValue(awaitdatabase.rawQuery("SELECT COUNT(*) FROM Test"));

assert(count==2);

// 关闭数据库

await   database.close();

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

使用示例如下所示:

其中有一些注意事项:

1,Transcaction 

2,支持批量操作

但是这里注意,这些操作返回结果,都会有一些开销,如果不考虑结果,可以使用。

事务期间,直到事务被提交,批量操作才能提交。

3,表和列的名字

通常避免使用SQLite关键字作为表名或者列名,例如以下其中之一。

如果必须使用如上,需要使用双引号转义,例如:

4,支持的列类型

首先,我们创建一个书籍类,包括书籍ID、书名、作者、价格、出版社等信息。

示例二:
finalString tableBook = 'book';

finalString columnId = '_id';

finalString columnName = 'name';

finalString columnAuthor = 'author';

finalString columnPrice = 'price';

finalString columnPublishingHouse = 'publishingHouse';

classBook {

 intid;

 String name;

 String author;

 doubleprice;

 String publishingHouse;

 Map<String, dynamic> toMap() {

 var map = <String, dynamic>{

 columnName: name,

 columnAuthor: author,

 columnPrice: price,

 columnPublishingHouse: publishingHouse

 };

 if(id != null) {

 map[columnId] = id;

 }

 returnmap;

 }

 Book();

 Book.fromMap(Map<String, dynamic> map) {

 id = map[columnId];

 name = map[columnName];

 author = map[columnAuthor];

 price = map[columnPrice];

 publishingHouse = map[columnPublishingHouse];

 }

}

2,创建对应的数据库文件和表

// 获取数据库文件的存储路径

 var databasesPath = await getDatabasesPath();

 String path = join(databasesPath, 'demo.db');

//根据数据库文件路径和数据库版本号创建数据库表

 db = await openDatabase(path, version: 1,

 onCreate: (Database db, intversion) async {

 await db.execute('''

  CREATE TABLE $tableBook (

  $columnId INTEGER PRIMARY KEY,

  $columnName TEXT,

  $columnAuthor TEXT,

  $columnPrice REAL,

  $columnPublishingHouse TEXT)

  ''');

 });

3,CRUD实现
// 插入一条书籍数据

Future<Book> insert(Book book) async {

book.id = await db.insert(tableBook, book.toMap());

returnbook;

}

// 查找所有书籍信息

Future<List<Book>> queryAll() async {

List<Map> maps = await db.query(tableBook, columns: [

columnId,

columnName,

columnAuthor,

columnPrice,

columnPublishingHouse

]);

if(maps == null|| maps.length == 0) {

returnnull;

}

List<Book> books = [];

for(inti = 0; i < maps.length; i++) {

books.add(Book.fromMap(maps[i]));

}

returnbooks;

}

// 根据ID查找书籍信息

Future<Book> getBook(intid) async {

List<Map> maps = await db.query(tableBook,

columns: [

 columnId,

 columnName,

 columnAuthor,

 columnPrice,

 columnPublishingHouse

],

where: '$columnId = ?',

whereArgs: [id]);

if(maps.length > 0) {

returnBook.fromMap(maps.first);

}

returnnull;

}

// 根据ID删除书籍信息

Future<int> delete(intid) async {

returnawait db.delete(tableBook, where: '$columnId = ?', whereArgs: [id]);

}

// 更新书籍信息

Future<int> update(Book book) async {

returnawait db.update(tableBook, book.toMap(),

where: '$columnId = ?', whereArgs: [book.id]);

}

4,关闭数据库,上文中已提示

5,CRUDUtils

_add() async {                                                                                                            Database db = await _open(); String sql = "INSERT INTO user_table(username,pwd) VALUES('$username','$pwd')";                                           //开启事务                                                                                                                    await db.transaction((txn) async {                                                                                int id = await txn.rawInsert(sql); });                                                                            await db.close();                                                                                                          setState(() {                                                                                                              _result = "插入username=$username,pwd=$pwd数据成功";                                                }) ;                                                                                                                               }                                                                                                                          _delete() async {                                                                                                       Database db = await _open();                                                                                     //删除最近一条                                                                                                              String sql = "DELETE FROM user_table where id in (select id from user_table order by id desc limit 1)";                                                                                                        int count = await db.rawDelete(sql);                                                                              await db.close();                                                                                                         setState(() {                                                                                                                 if (count == 1) {                                                                                                             _result = "删除成功,请查看";                                                                                    } else {                                                                                                                          _result = "删除0条数据或删除失败,请看log";                                                               } }); }                                                                                                               _update() async {                                                                                                        Database db = await _open();                                                                                    String sql = "UPDATE user_table SET pwd = ? WHERE id = ?";                                 int count = await db.rawUpdate(sql, ["654321", '1']); print(count);                                  await db.close();                                                                                                        setState(() {                                                                                                               _result = "更新数据成功,请查看";                                                                               }); }                                                                                                                               //批量增、改、删数据                                                                                                   _batch() async {                                                                                                           Database db = await _open();                                                                                     var batch = db.batch();                                                                                                batch.insert("user_table", {"username": "batchName1"});                                             batch.update("user_table", {"username": "batchName2"}, where: "username = ?",whereArgs: ["batchName1"]);                                                                                batch.delete("user_table", where: "username = ?", whereArgs: ["Leon"]);                   //返回每个数据库操作的结果组成的数组 [6, 3, 0]:新增返回id=6,修改了3条数据,删除了0条数据                                                                                                            var results = await batch.commit(); await db.close();                                                 setState(() {                                                                                                               _result = "批量增、改数据成功 "+results.toString();                                                     }); }                                                                                                               _queryNum() async {                                                                                                   Database db = await _open(); int count = Sqflite.firstIntValue(                                     await db.rawQuery(sql_query_count)); await db.close(); setState(() {                         _result = "数据条数:$count"; });                                                                                   }                                                                                                                               _query() async {                                                                                                            Database db = await _open(); List<Map> list = await db.rawQuery(sql_query);         await db.close(); setState(() { _result = "数据详情:$list"; });                                        } 

数据库的创建、打开,都需要先获取数据库文件的路径,获取到path之后Database db = await openDatabase(dbPath);获取数据库对象,注意数据库的操作全都是异步的,要用关键字await。

上一篇下一篇

猜你喜欢

热点阅读