欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter利用ORM框架簡化本地數(shù)據(jù)庫管理詳解

 更新時間:2023年04月10日 09:08:20   作者:島上碼農(nóng)  
使用?sqflite?相對來說還是有點復(fù)雜,比如遇到數(shù)據(jù)不兼容的時候需要手動轉(zhuǎn)換,增加了不少繁瑣的代碼。本篇我們就來介紹一個?ORM?框架,來簡化數(shù)據(jù)庫的管理,感興趣的可以了解一下

前言

前面兩篇我們介紹了使用 sqflite 管理 Flutter 本地 SQLite 數(shù)據(jù)庫。使用 sqflite 相對來說還是有點復(fù)雜,比如需要自己寫數(shù)據(jù)庫數(shù)據(jù)到實體類對象的轉(zhuǎn)換,遇到數(shù)據(jù)不兼容的時候需要手動轉(zhuǎn)換,增加了不少繁瑣的代碼。本篇我們就來介紹一個 ORM 框架,來簡化數(shù)據(jù)庫的管理,這個框架就是 floor。

floor 簡介

floor 是基于 sqflite 的一個輕量級的 ORM 框架,通過注解和代碼生成可以將數(shù)據(jù)庫數(shù)據(jù)直接映射為實體類對象。floor 內(nèi)置了很多操作數(shù)據(jù)庫的方法,比如增刪改查,讓我們快速接入數(shù)據(jù)庫。同時,也可以在注解中編寫 SQL來實現(xiàn)復(fù)雜的數(shù)據(jù)庫查詢,比如 IN 查詢、數(shù)據(jù)統(tǒng)計等等。通過注解和代碼生成能夠減少大量手寫代碼,提高我們的開發(fā)效率和代碼的可維護性。floor 的文檔非常完善,大家可以到github閱讀相關(guān)的文檔:pinchbv.github.io/floor/getti…。 floor 需要引入的開發(fā)依賴如下,都是用于基于注解生成代碼。

dev_dependencies:
    flutter_test:
        sdk: flutter

    # ...
    floor_generator: ^1.4.1
    build_runner: ^2.3.3

接下來我們就以之前的備忘錄為例,來看看使用 floor 后的改善。

ORM 映射

我們之前的備忘錄類 Memo 需要自己編寫 fromJsontoJson 方法來實現(xiàn)數(shù)據(jù)庫數(shù)據(jù)到實體類對象的轉(zhuǎn)換。此外,遇到 SQLite 不支持的數(shù)據(jù)類型(如 DateTimeList<String>)時,還需要處理轉(zhuǎn)換代碼。我們來看 floor 如何處理。 floor 將數(shù)據(jù)庫操作分為實體類和 DAO,實體類與數(shù)據(jù)庫的映射通過注解完成。例如我們的 Memo 類,調(diào)整后的代碼如下所示。

@entity
class Memo {
  @PrimaryKey(autoGenerate: true)
  final int? id;
  String title;
  String content;
  @ColumnInfo(name: 'created_time')
  DateTime createdTime;
  @ColumnInfo(name: 'modified_time')
  DateTime modifiedTime;
  List<String> tags;

  Memo({
    this.id,
    required this.title,
    required this.content,
    required this.createdTime,
    required this.modifiedTime,
    required this.tags,
  });
}

這里說明一下常見的注解:

  • @entity:表示這是一個實體類,會和數(shù)據(jù)庫的某個數(shù)據(jù)表映射,默認(rèn)表名就是類名。如果要手動指定表名,可以使用@Entity(tableName: tableName)通過 tableName 指定數(shù)據(jù)表名稱。floor 會自動根據(jù)@entity 注解生成創(chuàng)建數(shù)據(jù)表的 SQL 語句。
  • @primaryKey:表示字段為主鍵,如果需要使用自增主鍵,可以使用@PrimaryKey(autoGenerate: true)。
  • @ColumnInfo(name: name):設(shè)置實體類成員屬性和數(shù)據(jù)表字段的映射關(guān)系,默認(rèn) floor 使用的數(shù)據(jù)表字段名稱和類成員屬性名稱一致,如果需要指定數(shù)據(jù)表字段名,就可以使用這個注解。
  • @ignore:忽略某個成員屬性,即該屬性不產(chǎn)生相應(yīng)的數(shù)據(jù)表字段。注意,通過 get 方法產(chǎn)生的計算屬性默認(rèn)就會被忽略,例如長方形面積 double get area => width * height。

DAO 用于從數(shù)據(jù)庫查詢數(shù)據(jù)并轉(zhuǎn)換為實體類對象,從數(shù)據(jù)庫查詢數(shù)據(jù)和轉(zhuǎn)換的代碼通過注解直接生成。DAO 提供了基礎(chǔ)的插入、更新和刪除方法,這些方法可以通過注解@insert、@update @delete完成,不需要編寫 SQL。 同時,對于插入和更新可以設(shè)置沖突策略,策略可以是中止(abort)、回滾(rollback)、替換(replace)、忽略(ignore)、失?。╢ail)。其中除了替換以外,其他都是和數(shù)據(jù)庫事務(wù)有關(guān)。

@dao
abstract class MemoDao {
  @Query('SELECT * FROM Memo ORDER BY modified_time DESC')
  Future<List<Memo>> findAllMemos();

  @Query(
      'SELECT * FROM Memo WHERE title LIKE :searchKey OR content LIKE :searchKey ORDER BY modified_time DESC')
  Future<List<Memo>> findMemoWithSearchKey(String searchKey);

  @Query('SELECT * FROM Memo WHERE id = :id')
  Stream<Memo?> findMemoById(int id);

  @insert
  Future<void> insertMemo(Memo memo);

  @Update(onConflict: OnConflictStrategy.replace)
  Future<void> updateMemo(Memo memo);

  @delete
  Future<void> deleteMemo(Memo memo);
}

轉(zhuǎn)換器

使用 floor 可以統(tǒng)一 Dart 數(shù)據(jù)類型到 SQLite 字段的轉(zhuǎn)換方式。通過定義不同的類型轉(zhuǎn)換器TypeConverter實現(xiàn)數(shù)據(jù)庫和Dart 數(shù)據(jù)類型的轉(zhuǎn)換,從而避免了每個實體類都要單獨編寫轉(zhuǎn)換代碼。比如我們在備忘錄用到了兩個類型 DateTimeList<String> 就定義了對應(yīng)的轉(zhuǎn)換器。

class StringListConverter extends TypeConverter<List<String>, String> {
  @override
  List<String> decode(String databaseValue) {
    return databaseValue.isNotEmpty ? databaseValue.split('|') : [];
  }

  @override
  String encode(List<String> value) {
    return value.join('|');
  }
}

class DateTimeConverter extends TypeConverter<DateTime, int> {
  @override
  DateTime decode(int databaseValue) {
    return DateTime.fromMillisecondsSinceEpoch(databaseValue);
  }

  @override
  int encode(DateTime value) {
    return value.millisecondsSinceEpoch;
  }
}

使用轉(zhuǎn)換器只需要在定義數(shù)據(jù)庫FloorDatabase 的抽象類的時候引入到注解@TypeConverters就可以了。

@TypeConverters([StringListConverter, DateTimeConverter])
@Database(version: 1, entities: [Memo])
abstract class MemoDatabase extends FloorDatabase {
  MemoDao get memoDao;
}

代碼改造

通常來說 DAO 對象會在很多地方共用,適合使用單例方式來構(gòu)造。這里我們在App啟動的時候就使用 GetIt來實現(xiàn)MemoDao 的單例注冊。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final database =
      await $FloorMemoDatabase.databaseBuilder('app_database.db').build();

  final dao = database.memoDao;

  getIt.registerSingleton<MemoDao>(dao, signalsReady: true);

  runApp(const MyApp());
}

這里調(diào)用ensureInitialized這個方法是保證 Flutter 和原生交互的部分已經(jīng)完成,因為在 sqflite 中需要使用原生的文件存儲。 備忘錄列表的代碼改造涉及數(shù)據(jù)操作的有兩處,分別是列表刷新和刪除備忘錄。列表模糊搜索時需要自己組裝模糊搜索的字符,比如我們這里使用了百分號將搜索關(guān)鍵詞包裹實現(xiàn)任意匹配。刪除備忘錄需要根據(jù)是否有搜索調(diào)用不同的方法,這是因為對應(yīng)的 SQL 不同。

void _refreshMemoList({String? searchKey}) async {
  List<Memo> memoList = searchKey == null
      ? await GetIt.I<MemoDao>().findAllMemos()
      : await GetIt.I<MemoDao>().findMemoWithSearchKey('%$searchKey%');
  setState(() {
    _memoList = memoList;
  });
}

刪除就非常簡單了,直接調(diào)用刪除方法就好了。

void _deleteMemo(Memo memo) async {
    final confirmed = await _showDeleteConfirmationDialog(memo);
    if (confirmed != null && confirmed) {
      await GetIt.I<MemoDao>().deleteMemo(memo);
      _refreshMemoList();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        content: Text('已刪除 "${memo.title}"'),
        duration: const Duration(seconds: 2),
      ));
    }
  }

添加備忘錄的頁面只需要更改保存?zhèn)渫浀姆椒ǎ乙驗椴恍枰賹r間做轉(zhuǎn)換,方法更為簡潔。

Future<void> _saveMemo(BuildContext context) async {
  var memo = Memo(
      title: _title,
      content: _content,
      createdTime: DateTime.now(),
      modifiedTime: DateTime.now(),
      tags: _tags);
  // 保存?zhèn)渫?
  await GetIt.I<MemoDao>().insertMemo(memo);
}

編輯備忘錄頁面也類似,調(diào)用 updateMemo 方法即可完成保存。

Future<void> _saveMemo(BuildContext context) async {
  widget.memo.title = _title;
  widget.memo.content = _content;
  widget.memo.modifiedTime = DateTime.now();
  // 保存?zhèn)渫?
  await GetIt.I<MemoDao>().updateMemo(widget.memo);
}

總結(jié)

代碼已經(jīng)提交到:本地存儲相關(guān)代碼,注意如果更改了 ORM 相關(guān)的類,需要運行下面的命令重新生成代碼。

flutter packages pub run build_runner build

可以看到,通過 floor 這樣的 ORM 框架可以讓整個本地數(shù)據(jù)庫管理的代碼更為簡潔,復(fù)用性更高。如果說是本地數(shù)據(jù)存儲比較復(fù)雜的,推薦使用 ORM 框架來管理。

到此這篇關(guān)于Flutter利用ORM框架簡化本地數(shù)據(jù)庫管理詳解的文章就介紹到這了,更多相關(guān)Flutter ORM框架簡化本地數(shù)據(jù)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android仿美團分類下拉菜單實例代碼

    Android仿美團分類下拉菜單實例代碼

    這篇文章主要為大家詳細(xì)介紹了Android仿美團分類下拉菜單實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android中Glide加載庫的圖片緩存配置究極指南

    Android中Glide加載庫的圖片緩存配置究極指南

    這篇文章主要介紹了Android中Glide加載庫的圖片緩存配置究極指南,Glide是一款高人氣的安卓多媒體資源加載庫,本文對其緩存設(shè)置和優(yōu)化作了詳細(xì)講解,需要的朋友可以參考下
    2016-04-04
  • [Android] 通過GridView仿微信動態(tài)添加本地圖片示例代碼

    [Android] 通過GridView仿微信動態(tài)添加本地圖片示例代碼

    本篇文章主要介紹了[Android] 通過GridView仿微信動態(tài)添加本地圖片示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-01-01
  • 使用Android自定義控件實現(xiàn)滑動解鎖九宮格

    使用Android自定義控件實現(xiàn)滑動解鎖九宮格

    最近由于Android項目需要,要求做一個類似于支付寶的九宮格解鎖組件,下面小編給大家分享了具體實現(xiàn)代碼,需要的朋友可以參考下
    2015-10-10
  • 詳解Android中Service AIDL的使用

    詳解Android中Service AIDL的使用

    作為一名Android開發(fā)人員,如果沒聽過Service,那就有點說不過去了啊,Service是Android四大組件之一,它是不依賴于用戶界面的,就是因為Service不依賴與用戶界面,所以我們常常用于進行一些耗時的操作,比如:下載數(shù)據(jù)等;本文將詳細(xì)介紹Android中Service AIDL的使用。
    2021-06-06
  • Android開發(fā)之在程序中時時獲取logcat日志信息的方法(附demo源碼下載)

    Android開發(fā)之在程序中時時獲取logcat日志信息的方法(附demo源碼下載)

    這篇文章主要介紹了Android開發(fā)之在程序中時時獲取logcat日志信息的方法,結(jié)合實例形式較為詳細(xì)的分析了實時獲取logcat日志的原理、步驟與相關(guān)實現(xiàn)技巧,并附帶相應(yīng)的demo源碼供讀者下載參考,需要的朋友可以參考下
    2016-02-02
  • Android啟動頁優(yōu)化之實現(xiàn)應(yīng)用秒開

    Android啟動頁優(yōu)化之實現(xiàn)應(yīng)用秒開

    現(xiàn)在很多應(yīng)用都會在進入主界面之前,添加一個啟動頁,然后加入幾秒鐘的廣告,我覺得這個不能算是 “真正意義上的 “ 啟動頁,應(yīng)該叫廣告頁。
    2021-05-05
  • Android Studio綁定下拉框數(shù)據(jù)詳解

    Android Studio綁定下拉框數(shù)據(jù)詳解

    這篇文章主要為大家詳細(xì)介紹了Android Studio綁定下拉框數(shù)據(jù),Android Studio綁定網(wǎng)絡(luò)JSON數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android中SurfaceView用法簡單實例

    Android中SurfaceView用法簡單實例

    這篇文章主要介紹了Android中SurfaceView用法,以一個簡單的圖形繪制及改變位置實現(xiàn)方法分析了SurfaceView的使用技巧,需要的朋友可以參考下
    2015-10-10
  • Android Scroll滑動效果實例

    Android Scroll滑動效果實例

    這篇文章主要為大家分享了Android Scroll滑動效果實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評論