美文网首页Flutter&DartFlutter学习
哥哥手把手教你Flutter中SQFLite数据库的使用---粘

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

作者: 哥哥是欧巴Vitory | 来源:发表于2019-07-25 16:09 被阅读10次

    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。

    相关文章

      网友评论

        本文标题:哥哥手把手教你Flutter中SQFLite数据库的使用---粘

        本文链接:https://www.haomeiwen.com/subject/omwcrctx.html