Flutter-數(shù)據(jù)庫

我們平時(shí)開發(fā)android或者ios都有比較成熟的高級數(shù)據(jù)庫管理,但是目前flutter暫時(shí)沒有,所以我們目前數(shù)據(jù)存儲采用的是還是相對原生的sqflite。

先上工具類:

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite/sqlite_api.dart';
import 'package:yxk_app/utils/data_utils.dart';
import 'package:yxk_app/utils/log_utils.dart';

import 'db_bean_base.dart';

/// 數(shù)據(jù)庫存儲
class DbUtils {
  DbUtils._();

  // 數(shù)據(jù)庫路徑
  String databasesPath;
  // 數(shù)據(jù)庫
  Database database;
  // 數(shù)據(jù)庫版本
  int dbVersion = 1;

  static DbUtils dbUtils;

  static DbUtils getInstance() {
    if (null == dbUtils) dbUtils = DbUtils._();
    return dbUtils;
  }

  /// 打開數(shù)據(jù)庫
  Future openDb(String dbName) async {
    // 如果數(shù)據(jù)庫路徑不存在,賦值
    if (null == databasesPath || databasesPath.isEmpty)
      databasesPath = await getDatabasesPath();

    // 如果數(shù)據(jù)庫存在,而且數(shù)據(jù)庫沒有關(guān)閉,先關(guān)閉數(shù)據(jù)庫
    closeDb();

    database = await openDatabase(join(databasesPath, dbName + '.db'),
        version: dbVersion, onCreate: (Database db, int version) async {
      // 用戶表
      await db.execute(
          'CREATE TABLE UserInfo (userName TEXT PRIMARY KEY, nickName TEXT, headImgUrl TEXT, phone TEXT, idCard TEXT, telephone TEXT, emailYear TEXT, birthday TEXT, year TEXT, bankCard TEXT, province TEXT, city TEXT, county TEXT, town TEXT, address TEXT, sex INTEGER, status INTEGER, poorNumberCard TEXT, openBank TEXT, relationUser TEXT, relationName TEXT, appRole TEXT, createTime TEXT, updateTime Text)');
      // 收貨地址信息表
      await db.execute(
          'CREATE TABLE PickInfo (id TEXT PRIMARY KEY, userName TEXT, tel TEXT, receiver TEXT, province TEXT, city TEXT, county TEXT, address TEXT, status TEXT)');
    }, onUpgrade: (Database db, int oldVersion, int newVersion) {
      // 版本更新可能牽扯到重新插入表、刪除表、表中字段變更-具體更新相關(guān)sql語句進(jìn)行操作
    });
  }

  // 插入數(shù)據(jù)
  Future<void> insertItem<T extends DbBaseBean>(T t) async {
    if (null == database || !database.isOpen) return;
    Log.d("開始插入數(shù)據(jù):${t.toJson()}");

    // 插入操作
    await database.insert(
      t.getTableName(),
      t.toJson(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  /// 刪除數(shù)據(jù)
  Future<void> deleteItem<T extends DbBaseBean>(T t,
      {String key, String value}) async {
    if (null == database || !database.isOpen) return null;

    // 刪除表
    if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
      await database.delete(t.getTableName());
    } else {
      // 刪除數(shù)據(jù)
      await database.delete(
        t.getTableName(),
        where: (key + " = ?"),
        whereArgs: [value],
      );
    }
  }

  /// 更新數(shù)據(jù)
  Future<void> updateItem<T extends DbBaseBean>(
      T t, String key, String value) async {
    if (null == database || !database.isOpen) return null;

    // 更新數(shù)據(jù)
    await database.update(
      t.getTableName(),
      t.toJson(),
      where: (key + " = ?"),
      whereArgs: [value],
    );
  }

  // 查詢數(shù)據(jù)
  Future<List<T>> queryItems<T extends DbBaseBean>(T t,
      {String key = "", String value = ""}) async {
    if (null == database || !database.isOpen) return null;

    List<Map<String, dynamic>> maps = List();

    // 列表數(shù)據(jù)
    if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
      maps = await database.query(t.getTableName());
    } else {
      maps = await database.query(
        t.getTableName(),
        where: (key + " = ?"),
        whereArgs: [value],
      );
    }

    // map轉(zhuǎn)換為List集合
    return List.generate(maps.length, (i) {
      return t.fromJson(maps[i]);
    });
  }

  /// 關(guān)閉數(shù)據(jù)庫
  closeDb() async {
    // 如果數(shù)據(jù)庫存在,而且數(shù)據(jù)庫沒有關(guān)閉,先關(guān)閉數(shù)據(jù)庫
    if (null != database && database.isOpen) {
      await database.close();
      database = null;
    }
  }

  /// 刪除數(shù)據(jù)庫
  deleteDb(String dbName) async {
    // 如果數(shù)據(jù)庫路徑不存在,賦值
    if (null == databasesPath || databasesPath.isEmpty)
      databasesPath = await getDatabasesPath();

    await deleteDatabase(join(databasesPath, dbName + '.db'));
  }
}

我們里面引入一個(gè)DbBaseBean,主要是為了便于采用泛型,統(tǒng)一工具類調(diào)用方法。
使用方法:所有需要存儲的表對應(yīng)的實(shí)體類繼承該對象。

// 基礎(chǔ)bean,工具類操作依賴此bean
abstract class DbBaseBean {
  /// 實(shí)體轉(zhuǎn)換Map
  Map<String, dynamic> toJson();

  /// map轉(zhuǎn)實(shí)體
  DbBaseBean fromJson(Map<String, dynamic> map);

  /// 關(guān)聯(lián)表名稱
  String getTableName();
}

使用說明
1.我們的方法大多都是async方法,所以調(diào)用的時(shí)候一定要加上await
2.打開數(shù)據(jù)庫、用戶切換:
假如有兩個(gè)用戶,用戶號分別是"周杰倫"、"陳奕迅"
需要切換的時(shí)候直接調(diào)用

await DbUtils.getInstance().openDb("周杰倫");

3.工具類中增刪改查都有,只需要正常操作就可以了。
表關(guān)聯(lián)實(shí)體類的創(chuàng)建:

  • 加入相關(guān)引用
    dependencies:
    json_annotation: ^3.0.0
    analyzer: 0.38.2
    dev_dependencies:
    flutter_test:
    sdk: flutter
    build_runner: ^1.7.0
    json_serializable: ^3.2.0
  • 打開網(wǎng)頁對數(shù)據(jù)進(jìn)行序列化生成.g文件
    https://caijinglong.github.io/json2dart/index.html
  • 執(zhí)行命令,生成需要的文件
    Terminal運(yùn)行:fflutter packages pub run build_runner build --delete-conflicting-outputs(刪除后重建)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容