首頁 > 軟體

Flutter中資料庫的使用教學詳解

2022-04-12 19:00:42

在Flutter開發過程中,我門有時候需要對一些資料進行原生的持久化儲存,使用sp檔案形式雖然也能解決問題,但是有時資料量較大的時候,顯然我們檔案形式就不太合適了,這時候我們就需要使用資料庫進行儲存,我們知道在原生中有系統提供的輕量級sqlite資料庫,在Flutter強大的生態環境中,也有這樣一個資料庫外掛sqflite: ^2.0.2可以同時在Androud、iOS中進行資料庫操作。

1、 建立資料庫:這裡我以儲存我的搜尋歷史記錄為例

首先匯入:

import 'package:sqflite/sqflite.dart';

這裡我建立了一個資料庫幫助類,為了以後資料庫更新、升級等作準備:

程式碼實現:主要是對Database這個類的獲取進行了封裝。

/// 資料庫幫助類
class DbHelper {

  final String path = "laoli.db"; // 資料庫名稱 一般不變
 //資料庫中的表名字 這裡是我存錯歷史搜尋記錄的表
  static final searchTab = "SearchHistory";
   //私有構造
  DbHelper._();
  static DbHelper? _instance;
  static DbHelper get instance => _getInstance();
  factory DbHelper() {
    return instance;
  }
  static DbHelper _getInstance() {
    if (_instance == null) {
      _instance = DbHelper._();
    }
    return _instance ?? DbHelper._();
  }

/// 資料庫預設儲存的路徑
  /// SQLite 資料庫是檔案系統中由路徑標識的檔案。如果是relative,
  /// 這個路徑是相對於 獲取的路徑getDatabasesPath(),
  /// Android預設的資料庫目錄,
  /// iOS/MacOS的documents目錄。

  Future<Database>? _db;

  Future<Database>? getDb() {
    _db ??= _initDb();
    return _db;
  }

  // Guaranteed to be called only once.保證只呼叫一次
  Future<Database> _initDb() async {
  // 這裡是我們真正建立資料庫的地方 vserion代表資料庫的版本,如果版本改變
  //,則db會呼叫onUpgrade方法進行更新操作
    final db =
        await openDatabase(this.path, version: 1, onCreate: (db, version) {
      // 資料庫建立完成
      // 建立表 一個自增id 一個text
db.execute("create table $searchTab (id integer primary key autoincrement, name text not null)");      
    }, onUpgrade: (db, oldV, newV) {
      // 升級資料庫呼叫 
    ///  db 資料庫
   ///   oldV 舊版本號
   //   newV 新版本號
   //   升級完成就不會在呼叫這個方法了
    });

return db;
  }

// 關閉資料庫
  close() async {
    await _db?.then((value) => value.close());
  }
}

java後臺開發過程中,資料庫肯定都會分層設計,這樣的好處可以在使用的過程中極大的提高程式碼的健壯性以及降低後期的維護成本,在移動前端雖然我們用資料庫的地方跟後臺相比少之又少,但是我還是建議也對資料庫進行分層處理操作,雖然不分層也能實現,但是這樣也可以降低我們的對於程式碼的維護成本以及良好的程式設計習慣。廢話不多說,接下來我們需要建立處理資料的dao層。

這裡sqflite封裝了一些常用的sql語法,比如增刪改查,我們就不需要自己去寫sql語法了,這裡我簡答封裝了下增刪改查的方法。

具體程式碼:

/// 資料操作類
class DbSearchHistoryDao {
  /// 增
  static insert(String text) {
    // 去重
    queryAll().then((value) {
      bool isAdd = true;
      for (var data in value) {
        if (data.name == text) {
          isAdd = false;
          break;
        }
      }
      if (isAdd) {
        DbHelper.instance.getDb()?.then((value) => value.insert(
              DbHelper.searchTab,
              DbSearchHotBean(name: text).toJson(),
            ));
      }
    });
  }

  /// 刪 全部
  static deleteAll() {
    DbHelper.instance.getDb()?.then((value) => value.delete(
          DbHelper.searchTab,
        ));
  }

  /// 更新資料 通過id更新表內具體行的資料
  static update(DbSearchHotBean dbSearchHotBean) {
    DbHelper.instance.getDb()?.then((value) => value.update(
      DbHelper.searchTab,
      dbSearchHotBean.toJson(),//具體更新的資料
      where: "id = ?"//通過id查詢需要更新的資料
      ,whereArgs: [dbSearchHotBean.id]
    ));
  }

  /// 通過name查具體的實體類
  static Future<DbSearchHotBean?> getBean(String name) async {
  var db = await DbHelper.instance.getDb();
  var maps = await db?.query(DbHelper.searchTab,
    columns: ['id','name'],// 獲取實體類的哪些欄位 預設全部
    where: 'name = ?',//通過實體類中的name欄位
    whereArgs: [name]);//具體name的值 限定資料
  if(maps!=null && maps.length > 0) {
       return DbSearchHotBean.fromJson(maps.first);
  }
  return null;
  }

  /// 查 全部all
  static Future<List<DbSearchHotBean>> queryAll() async {
    List<DbSearchHotBean> list = [];
    await DbHelper.instance
        .getDb()
        ?.then((db) => db.query(DbHelper.searchTab).then((value) {
              for (var data in value) {
                list.add(DbSearchHotBean.fromJson(data));
              }
            }));
    return list;
  }
}

實體類:雖然只有一個欄位,但是建立實體類方便以後擴充套件。

class DbSearchHotBean {
  int? id;
  String? name; // 搜尋詞

  DbSearchHotBean({this.id,required this.name});

  DbSearchHotBean.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
  }

  Map<String, String?> toJson() {
    var map = <String, String?>{};
    map['id'] = id?.toString() ;
    map['name'] = name ?? "";

    return map;
  }
}

具體用法就非常簡單了

增:DbSearchHistoryDao.insert(”搜尋詞“);

刪全部:DbSearchHistoryDao.deleteAll();

改:例如將水改為火, 找到水的實體通過自增id修改name

DbSearchHistoryDao.getBean("水").then((value){
  if(value!=null){
    DbSearchHistoryDao.update(DbSearchHotBean(id: value.id,name: "火"));
  }
});

查全部:await DbSearchHistoryDao.queryAll();

到這裡資料庫的基本用法就介紹完了,當然部分操作比如刪指定資料,批次修改、批次刪除等操作可以用 到批次處理操作,這裡就不過多介紹了,有需要的可以檢視作者檔案。連結

batch = db.batch();
batch.insert('Test', {'name': 'item'});
batch.update('Test', {'name': 'new_item'}, where: 'name = ?', whereArgs: ['item']);
batch.delete('Test', where: 'name = ?', whereArgs: ['item']);
results = await batch.commit();

總結

資料庫操作總體上沒什麼難度,但是當我們資料量比較多的時候,資料表結構的設計就有一定的技術含量了,還有就是我們對於一些sql語句的掌握,因為此外掛幫我們封裝了常用的功能,如果有比較特殊的需求,還是需要我們掌握一定的sql語法才行,這裡就簡單的介紹一些常用的方法,在移動前端估計也基本夠用了~

到此這篇關於Flutter中資料庫的使用教學詳解的文章就介紹到這了,更多相關Flutter資料庫內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com