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( 'SELECT v.id, v.name, v.desc, v.locale, uf.hash, uf.ext, v.created_at, v.updated_at from vegetables v LEFT OUTER JOIN upload_file_morph ufm on v.id = ufm.related_id LEFT OUTER JOIN upload_file uf on ufm.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';@daoabstract class VegetableDao { @Query('SELECT * FROM vegetables_v') Future<List<VegetableV>> findAll();}
创立Database治理类[project_root]/lib/app/data/database.dart
import 'dart:async';import 'package:floor/floor.dart';import 'package:sqflite/sqflite.dart' as sqflite;// daosimport 'dao/vegetable_dao.dart';// entitysimport '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<DbService> 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 = await rootBundle.load("assets/db/data.db"); List<int> 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<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await initServices(); runApp( GetMaterialApp( title: "Application", initialRoute: AppPages.INITIAL, getPages: AppPages.routes, ), );}Future<void> 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<List<VegetableV>>([]); @override void onInit() { super.onInit(); } @override void onReady() { super.onReady(); } Future<void> getAllVegetables() async { final result = await DbService.to.db.vegetableDao.findAll(); vegetables.value = result; } @override void onClose() {}}
简略测试一下
controller.getAllVegetables(); Future<void> getAllVegetables() async { final result = await DbService.to.db.vegetableDao.findAll(); vegetables.value = result; print(result); }
失去
I/flutter ( 7396): starting services ...I/flutter ( 7396): onOpen databaseI/flutter ( 7396): /data/user/0/com.nasawz.strapi_flutter_internation_poc.strapi_flutter_internation_poc/databasesI/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 initializedI/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<HomeController> { @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, ), ], ), ), ], ), ), ); })), ); }}
上一篇:整顿Sqlite数据库与图片