https://pub.dev/packages/floor
Định cấu hình tham chiếu pubspec.yaml
của thư viện phụ thuộc trong dự án Flutter
dependencies:
flutter:
sdk: flutter
floor: ^1.2.0
dev_dependencies:
floor_generator: ^1.2.0
build_runner: ^2.1.2
Tạo thực thể và xem [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;
}
Để biết chi tiết cụ thể, vui lòng tham khảo https://floor.codes/database-views/
Tạo "Đối tượng truy cập dữ liệu" theo chế độ xem [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<List<VegetableV>> findAll();
}
Tạo lớp quản lý cơ sở dữ liệu [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;
}
Trình tạo mã của Run 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)
Điều này sẽ tạo ra một database.g.dart
trong cùng thư mục với database.dart
Sử dụng lược đồ Dịch vụ của GetX để tạo dịch vụ db [project_root]/lib/app/common/services/db_service.dart.dart
Hãy đặc biệt chú ý ở đây
Không giống như tài liệu chính thức của Sàn, Sàn sẽ tạo cơ sở dữ liệu sqlite dựa trên thực thể. Tôi sẽ cung cấp các tệp cơ sở dữ liệu hiện có cho Sàn để sử dụng mà không cần tạo tệp cơ sở dữ liệu mới.
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;
}
}
Khởi tạo 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...');
}
Sửa đổi mã home_controller để đọc cơ sở dữ liệu 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() {}
}
Kiểm tra nó trong thời gian ngắn
controller.getAllVegetables();
Future<void> getAllVegetables() async {
final result = await DbService.to.db.vegetableDao.findAll();
vegetables.value = result;
print(result);
}
ngoài
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']
sự thành công! Dữ liệu được đọc ra.
Sử dụng tính năng Obx của GetX để hiển thị dữ liệu trên giao diện
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,
),
],
),
),
],
),
),
);
})),
);
}
}