Flutter 25: 圖解關乎 SQL 數據庫的二三事

??????小菜剛剛學習一下關于數據存儲方面的小知識點,用 sqflite 對數據庫進行基本操作。sqflite 為三方 pub 通用的引入方式。小菜僅對數據庫的基本操作進行學習整理。

集成方式

  1. pubspec.yaml 中添加 sqflite: any
  2. 在相應的 .dart 文件中添加引用 import 'package:sqflite/sqflite.dart';
  3. 根據需求對數據存儲進行具體的 SQL 操作,如下:

SQL 操作

1. 創建數據庫

??????sqflite 創建數據庫時優先創建一個路徑,用來存儲數據庫。注:對于數據庫的操作都是耗時操作,都要通過 asyncawait 異步處理。

FlatButton(
    color: Colors.blue,
    child: Text('創建一個 flutter_app.db 數據庫'),
    onPressed: () async {
      var databasesPath = await getDatabasesPath();
      path = join(databasesPath, 'flutter_app.db');
    }),

2. 創建數據表

??????借助 db.execute 來創建一張數據表,跟普通的 SQL 方式相同。

FlatButton(
    color: Colors.blue,
    child: Text('創建一張 user 表'),
    onPressed: () async {
      db = await openDatabase(path, version: 1,
          onCreate: (Database db, int version) async {
        await db.execute(
            'CREATE TABLE User (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, address TEXT)');
      });
    }),

3. 【增】插入數據

??????借助 rawInsertdb.insert 對數據庫表數據進行插入。根本上都是通過 insert into 方式插入數據表。

// db.transaction
_transactionOneUser(UserBean userBean) async {
  await db.transaction((txn) async {
    await txn.rawInsert(
        'INSERT INTO User(name, age, address) VALUES(${userBean.name}, '
        '${userBean.age},'
        '${userBean.address}'
        ')');
  });
}

// db.insert
_insertOneUser(var tableName, UserBean userBean) async {
  await db.insert(tableName, userBean.toMap());
}

4. 【查】查詢數據

??????借助 rawQuerydb.select 對數據庫表信息進行查詢,是操作最靈活對部分,配合各種 SQL 語句進行處理。

// db.rawQuery
Future<List<Map>> _getUserList() async {
  List<Map> list = await db.rawQuery('SELECT * FROM User');
  return list;
}

// db.query
Future<List<Map>> _getUserByName(var tableName, var name) async {
  List<Map> list =
      await db.query(tableName, where: 'name = ?', whereArgs: [name]);
  return list;
}

5. 【刪】刪除數據

??????借助 rawDeletedb.delete 對數據庫表進行數據刪除,小菜測試刪除 id = 0和1 的對應數據,sqflite 內部已處理好,若數據庫表不存在也不會報異常。

// rawDelete
_deleteRawUserByID(int id) async {
  return await db.transaction((txn) async {
    await txn.rawDelete('DELETE FROM User WHERE id = ${id}');
  });
}

// db.delete
_deleteUserByID(var tableName, int id) async {
  return await db.delete(tableName, where: 'id = ?', whereArgs: [id]);
}

6. 【改】更新數據

??????借助 rawUpdatedb.update 對數據庫表進行內容數據更新,可根據需求變更固定字段或整條數據。

// rawUpdate
_updateRawUser(var userBean) async {
  return await db.transaction((txn) async {
    await txn.rawUpdate('UPDATE User SET address = "${userBean.address}" '
        'WHERE name = "${userBean.name}"');
  });
}

// db.update
Future<int> _updateUser(var tableName, var userBean) async {
  return await db.update(tableName, userBean.toMap(),
      where: 'name = ?', whereArgs: [userBean.name]);
}

7. 刪除數據表

??????小菜剛接觸數據庫,沒有找到直接刪除表的方式,沒有類似 drop 的方法,如果有哪位大神了解請多多指導。注:若用如下方式只會刪除當前表中所有數據而不會刪除表。

onPressed: () async {
  await db.delete('User');
}

8. 刪除數據庫

??????刪除數據庫與創建數據庫相對應,直接對路徑進行操作。

FlatButton(
    color: Colors.blue,
    child: Text('刪除數據庫', style: TextStyle(color: Colors.white)),
    onPressed: () async {
      await deleteDatabase(path);
    })

注意事項

  1. 建議在對數據庫表進行增刪改查前優先判斷數據庫是否存在,可統一封裝方法以降低異常;
  2. 對于數據庫表的增刪改查,小菜使用了兩種方式:一種是直接 db.增刪改查,另一種是 db.transaction 后對回調 raw+增刪改查,兩種的區別是,第一種使用更便捷,可直接修改整條數據;第二種使用更靈活,可對部分數據字段進行調整,可以看圖例中的【更新】結果;
  3. 在使用 db.transaction 對數據庫表進行增刪改查時要注意 SQL 語句的完整性,包括傳遞 String 類型參數時要加引號,執行的是一個完整的 SQL 語句。

??????數據庫的操作靈活多樣,小菜剛剛嘗試,本篇僅記錄一下基本的使用情況,對于更多靈活的方法會繼續嘗試整理,有問題的地方請大家多多指導。

來源:阿策小和尚

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容