sql >> データベース >  >> RDS >> SQLite

オフライン国際化アプリを作成する方法:Sqliteデータベースを使用する

    https://pub.dev/packages/floor

    参照pubspec.yamlを構成します Flutterプロジェクトの依存ライブラリの

    dependencies:
      flutter:
        sdk: flutter
      floor: ^1.2.0
    
    dev_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-views/

    を参照してください。

    ビュー[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();
    }
    
    

    データベース管理クラス[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.g.dartが生成されます database.dartと同じディレクトリにあります

    GetXのサービススキームを使用して、dbサービス[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 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<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,
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              })),
        );
      }
    }
    
    


    1. MariaDB JSON_QUOTE()の説明

    2. グループ化された実行中のMAX(またはMIN)の維持

    3. ClusterControlCLIからPostgreSQLデータベースを管理する方法

    4. 数値の列値のみを取得するにはどうすればよいですか?