Strapi助力Flutter开发国际化App|Strapi助力Flutter开发国际化App - 使用Sqlite数据库

https://pub.dev/packages/floor
在Flutter项目中配置依赖库的引用pubspec.yaml
dependencies: flutter: sdk: flutter floor: ^1.2.0dev_dependencies: floor_generator: ^1.2.0 build_runner: ^2.1.2

创建实体与视图[project_root]/lib/app/data/entity/vegetalbe.dart
import 'package:floor/floor.dart'; @Entity(tableName: "vegetables") class Vegetable { @PrimaryKey(autoGenerate: true) final int? id; final String name; final String locale; final String desc; @ColumnInfo(name: 'created_at') final int createTime; @ColumnInfo(name: 'updated_at') final int updateTime; Vegetable( this.id, this.name, this.locale, this.desc, { int? createTime, int? updateTime, }): this.createTime = createTime ?? DateTime.now().millisecondsSinceEpoch, this.updateTime = updateTime ?? DateTime.now().millisecondsSinceEpoch; }@DatabaseView( 'SELECTv.id,v.name,v.desc,v.locale,uf.hash,uf.ext,v.created_at,v.updated_at fromvegetables v LEFT OUTER JOIN upload_file_morph ufm onv.id = ufm.related_id LEFT OUTER JOIN upload_file uf onufm.upload_file_id = uf.id; ', viewName: "vegetables_v") class VegetableV { final int id; final String name; final String locale; final String? desc; final String? hash; final String? ext; @ColumnInfo(name: 'created_at') final int createTime; @ColumnInfo(name: 'updated_at') final int updateTime; VegetableV( this.id, this.name, this.locale, this.desc, this.hash, this.ext, { int? createTime, int? updateTime, }): this.createTime = createTime ?? DateTime.now().millisecondsSinceEpoch, this.updateTime = updateTime ?? DateTime.now().millisecondsSinceEpoch; }

具体详情可参考 https://floor.codes/database-...
根据视图创建"Data Access Objects"[project_root]/lib/app/data/dao/vegetalbe_dao.dart
import 'package:floor/floor.dart'; import 'package:strapi_flutter_internation_poc/app/data/entity/vegetable.dart'; @dao abstract class VegetableDao { @Query('SELECT * FROM vegetables_v') Future> findAll(); }

创建Database管理类[project_root]/lib/app/data/database.dart
import 'dart:async'; import 'package:floor/floor.dart'; import 'package:sqflite/sqflite.dart' as sqflite; // daos import 'dao/vegetable_dao.dart'; // entitys import 'entity/vegetable.dart'; part 'database.g.dart'; // the generated code will be there@Database(version: 1, entities: [Vegetable], views: [VegetableV]) abstract class AppDatabase extends FloorDatabase { VegetableDao get vegetableDao; }

运行Floor的代码生成器
flutter packages pub run build_runner build [INFO] Generating build script... [INFO] Generating build script completed, took 480ms[INFO] Initializing inputs [INFO] Reading cached asset graph... [INFO] Reading cached asset graph completed, took 67ms[INFO] Checking for updates since last build... [INFO] Checking for updates since last build completed, took 651ms[INFO] Running build... [INFO] 1.1s elapsed, 0/1 actions completed. [INFO] 2.2s elapsed, 0/1 actions completed. [INFO] 4.0s elapsed, 0/1 actions completed. [INFO] 8.4s elapsed, 0/1 actions completed. [INFO] Running build completed, took 8.8s[INFO] Caching finalized dependency graph... [INFO] Caching finalized dependency graph completed, took 34ms[INFO] Succeeded after 8.8s with 2 outputs (2 actions)

这里会生成一个与database.dart同目录的database.g.dart
使用GetX的Service方案创建db的service [project_root]/lib/app/common/services/db_service.dart.dart
这里要特别注意一下
和Floor官方的文档介绍不同,Floor会根据实体生成一个sqlite数据库,我这里会将现有的数据库文件提供给Floor使用不生成新的数据库文件。
import 'dart:io'; import 'package:get/get.dart'; import 'package:path/path.dart'; import 'package:floor/floor.dart'; import 'package:flutter/services.dart'; import 'package:sqflite/sqflite.dart'; import 'package:strapi_flutter_internation_poc/app/data/database.dart'; class DbService extends GetxService { static DbService get to => Get.find(); late AppDatabase db; Future init() async { final callback = Callback( onCreate: (database, version) {}, onOpen: (database) { print('onOpen database'); getDatabasesPath().then((value) => print(value)); }, onUpgrade: (database, startVersion, endVersion) {}, ); var dbDir = await getDatabasesPath(); var dbPath = join(dbDir, "app_database.db"); await deleteDatabase(dbPath); ByteData data = https://www.it610.com/article/await rootBundle.load("assets/db/data.db"); List bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); await File(dbPath).writeAsBytes(bytes); db = await $FloorAppDatabase .databaseBuilder(dbPath) .addCallback(callback) .build(); return this; } }

实例化DbService [project_root]/lib/main.dart
Future main() async { WidgetsFlutterBinding.ensureInitialized(); await initServices(); runApp( GetMaterialApp( title: "Application", initialRoute: AppPages.INITIAL, getPages: AppPages.routes, ), ); }Future initServices() async { print('starting services ...'); await Get.putAsync(() => DbService().init()); print('All services started...'); }

修改home_controller代码读取Sqlite数据库 [project_root]/lib/app/modules/home/controllers/home_controller.dart
import 'package:get/get.dart'; import 'package:strapi_flutter_internation_poc/app/common/services/db_service.dart'; import 'package:strapi_flutter_internation_poc/app/data/entity/vegetable.dart'; class HomeController extends GetxController { final vegetables = Rx>([]); @override void onInit() { super.onInit(); }@override void onReady() { super.onReady(); }Future getAllVegetables() async { final result = await DbService.to.db.vegetableDao.findAll(); vegetables.value = https://www.it610.com/article/result; }@override void onClose() {} }

简单测试一下
controller.getAllVegetables(); Future getAllVegetables() async { final result = await DbService.to.db.vegetableDao.findAll(); vegetables.value = https://www.it610.com/article/result; print(result); }

得到
I/flutter ( 7396): starting services ... I/flutter ( 7396): onOpen database I/flutter ( 7396): /data/user/0/com.nasawz.strapi_flutter_internation_poc.strapi_flutter_internation_poc/databases I/flutter ( 7396): All services started... [GETX] Instance "DbService" has been created [GETX] Instance "DbService" has been initialized [GETX] Instance "GetMaterialController" has been created [GETX] Instance "GetMaterialController" has been initialized [GETX] GOING TO ROUTE /home [GETX] Instance "HomeController" has been created [GETX] Instance "HomeController" has been initialized I/flutter ( 7396): [Instance of 'VegetableV', Instance of 'VegetableV', Instance of 'VegetableV', Instance of 'VegetableV', Instance of 'VegetableV', Instance of 'VegetableV', Instance of 'VegetableV', Instance of 'VegetableV']

成功! 数据都读取出来了。
使用GetX的Obx特性把数据显示到界面上
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/home_controller.dart'; class HomeView extends GetView { @override Widget build(BuildContext context) { controller.getAllVegetables(); return Scaffold( appBar: AppBar( title: Text('Vegetables'), centerTitle: true, ), body: Obx(() => ListView.builder( itemCount: controller.vegetables.value.length, itemBuilder: (context, index) { var vegetable = controller.vegetables.value[index]; return Padding( padding: const EdgeInsets.all(18.0), child: Container( child: Row( children: [ Container( // color: Colors.red, child: Image.asset( 'strapi/public/uploads/thumbnail_${vegetable.hash}${vegetable.ext}', fit: BoxFit.contain, width: 140, height: 140, ), ), Container( width: Get.width - 18 * 2 - 140 - 18, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( vegetable.name, style: Get.textTheme.headline6, ), Text( vegetable.desc!, style: Get.textTheme.subtitle1, maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ), ); })), ); } }

Strapi助力Flutter开发国际化App|Strapi助力Flutter开发国际化App - 使用Sqlite数据库
文章图片

【Strapi助力Flutter开发国际化App|Strapi助力Flutter开发国际化App - 使用Sqlite数据库】上一篇:整理Sqlite数据库与图片

    推荐阅读