zoukankan      html  css  js  c++  java
  • Flutter: moor_flutter库,简化sqlite操作

    install

    dependencies:
      ...
      moor_flutter:
    
    dev_dependencies:
     ...
      moor_generator:
      build_runner:
    

    libdbmoor.db.dart

    import 'package:moor_flutter/moor_flutter.dart';
    
    part 'moor.db.g.dart';
    
    // 建表
    class Tasks extends Table {
      IntColumn get id => integer().autoIncrement()();
      TextColumn get name => text().withLength(min: 1, max: 50)();
      DateTimeColumn get dueData => dateTime().nullable()();
      BoolColumn get completed => boolean().withDefault(const Constant(false))();
    }
    
    @UseMoor(tables: [Tasks])
    class AppDatabase extends _$AppDatabase {
      AppDatabase()
          : super(FlutterQueryExecutor.inDatabaseFolder(path: 'db.sqlite'));
      @override
      int get schemaVersion => 1;
    
      Future<List<Task>> get getAllTasks => select(tasks).get();
    
      /// 每当基础数据发生变化时,都会发出新项
      Stream<List<Task>> watchAllTasks() => select(tasks).watch();
    
      /// 插入一条数据
      Future<int> insertTask({
        String name,
        DateTime dueData,
      }) =>
          into(tasks).insert(
            TasksCompanion(
              name: Value(name),
              dueData: Value(dueData),
            ),
          );
    
      /// 更新一条数据
      Future<bool> updateTask(Task task) => update(tasks).replace(task);
    
      /// 删除一条数据
      Future<int> deleteTask(Task task) => delete(tasks).delete(task);
    }
    

    libstoremainmain.store.dart

    import 'package:flutter_moor_demo/db/moor.db.dart';
    
    class MainStore {
      final dbService = DBService();
    }
    
    class DBService {
      final database = AppDatabase();
      Stream<List<Task>> get tasks$ =>
          database.watchAllTasks().map((List<Task> tasks) {
            /// 排序,把完成的排在后面
            tasks.sort(
              (a, b) => _getInt(a.completed).compareTo(_getInt(b.completed)),
            );
            return tasks;
          });
      int _getInt(bool b) {
        return b ? 1 : 0;
      }
    }
    
    final MainStore mainStore = MainStore();
    

    libmain.dart

    import 'package:flutter/material.dart';
    import 'package:flutter_moor_demo/store/main/main.store.dart';
    
    import 'db/moor.db.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      DateTime newTaskDate;
      TextEditingController controller;
      @override
      void initState() {
        super.initState();
        controller = TextEditingController();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Tasks'),
          ),
          body: Column(
            children: <Widget>[
              Expanded(
                child: StreamBuilder<List<Task>>(
                  stream: mainStore.dbService.tasks$,
                  initialData: List<Task>(),
                  builder: (context, snap) {
                    if (snap.connectionState == ConnectionState.active) {
                      List<Task> tasks = snap.data;
                      if (tasks.isEmpty) return Center(child: Text('Not Data'));
                      return ListView.builder(
                        itemCount: tasks.length + 1,
                        itemBuilder: (context, int index) {
                          if (index == 0) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Center(child: Text('taskS #${tasks.length}')),
                            );
                          }
                          final task = tasks[index - 1];
                          return Dismissible(
                            key: ValueKey(task.id),
                            background: Container(color: Colors.red),
                            onDismissed: (DismissDirection d) {
                              mainStore.dbService.database.deleteTask(task);
                            },
                            child: CheckboxListTile(
                              title: Text(task.name),
                              subtitle: Text(task.dueData?.toString() ?? 'No date'),
                              value: task.completed,
                              onChanged: (bool nv) {
                                mainStore.dbService.database
                                    .updateTask(task.copyWith(completed: nv));
                              },
                            ),
                          );
                        },
                      );
                    } else if (snap.connectionState == ConnectionState.waiting) {
                      return Center(child: CircularProgressIndicator());
                    } else {
                      return SizedBox();
                    }
                  },
                ),
              ),
              ListTile(
                title: TextField(
                  controller: controller,
                  decoration: InputDecoration(hintText: 'Task Name'),
                  onSubmitted: (String v) {
                    mainStore.dbService.database.insertTask(
                      name: v.trim(),
                      dueData: newTaskDate,
                    );
    
                    _reset();
                  },
                ),
                trailing: IconButton(
                  icon: Icon(Icons.calendar_today),
                  onPressed: () async {
                    DateTime now = DateTime.now();
                    Duration d = Duration(days: 10);
                    newTaskDate = await showDatePicker(
                        context: context,
                        initialDate: now,
                        firstDate: now.subtract(d),
                        lastDate: now.add(d));
                  },
                ),
              )
            ],
          ),
        );
      }
    
      void _reset() {
        setState(() {
          controller.clear();
          newTaskDate = null;
        });
      }
    }
    

    moor_flutter迁移至moor_ffi

    import 'dart:io';
    
    import 'package:moor/moor.dart';
    import 'package:moor_ffi/moor_ffi.dart';
    import 'package:path_provider/path_provider.dart';
    import 'package:path/path.dart' as p;
    
    part 'tabel.g.dart';
    
    // 这将为我们生成一个名为todos的表。 该表的行将
    // 由称为Todo的类表示
    class Todos extends Table {
      IntColumn get id => integer().autoIncrement()();
      TextColumn get title => text().withLength(min: 6, max: 32)();
      TextColumn get content => text().named('body')();
      IntColumn get category => integer().nullable()();
    }
    
    // 这将使moor生成一个名为"Category"的类来表示该表中的一行。
    // 在表格名称中,默认情况下,将使用"Categorie",因为它只会去除结尾的"s"
    @DataClassName("Category")
    class Categories extends Table {
      IntColumn get id => integer().autoIncrement()();
      TextColumn get description => text()();
    }
    
    LazyDatabase _openConnection() {
      // LazyDatabase实用程序使我们能够找到文件异步的正确位置。
      return LazyDatabase(() async {
        // 将数据库文件db.sqlite放入documents文件夹
        // 为您的应用.
        final dbFolder = await getApplicationDocumentsDirectory();
        final file = File(p.join(dbFolder.path, 'db.sqlite'));
        return VmDatabase(file);
      });
    }
    
    // 此注释告诉moor准备使用两个
    // 我们刚刚定义的表格。 稍后我们将介绍如何使用该数据库类
    @UseMoor(tables: [Todos, Categories])
    class MyDatabase extends _$MyDatabase {
      // 我们通过这个构造函数告诉数据库在哪里存储数据
      MyDatabase() : super(_openConnection());
    
      // 您应该在更改或添加表定义时增加该数字
      // 本自述文件稍后将介绍迁移
      @override
      int get schemaVersion => 1;
    
      Stream<List<Todo>> allTodos() {
        return (select(todos)).watch();
      }
    
      Future<int> add(Insertable<Todo> d) {
        return into(todos).insert(d);
      }
    }
    

    使用

    import 'package:flutter/material.dart';
    import 'package:flutter_demo/db/tabel.dart';
    
    MyDatabase db;
    void main() {
      db = MyDatabase();
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      int _id = 1;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Home Page'),
          ),
          body: StreamBuilder<List<Todo>>(
            stream: db.allTodos(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting ||
                  !snapshot.hasData) return SizedBox();
              return ListView(
                children: snapshot.data.map((it) {
                  // 这里表的字段和上面定义的不一样
                  return ListTile(
                    key: ValueKey(it.id),
                    title: Text(it.title),
                    subtitle: Text(it.content),
                  );
                }).toList(),
              );
            },
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () {
              setState(() {
                _id++;
              });
              // 插入新数据
              var newTodo = TodosCompanion.insert(
                  title: '#$_id new title', content: '#$_id content');
              db.add(newTodo);
            },
          ),
        );
      }
    }
    
  • 相关阅读:
    celery异步任务
    redis过期策略与内存淘汰机制分析
    爬虫数据去重-布隆过滤器
    scrapy-redis数据去重与分布式框架
    redis哨兵机制
    C#从零单排上王者系列---元组
    玩转VSCode插件之Remote-SSH
    C#从零单排上王者系列---数据类型
    Cassandra之Docker环境实践
    centos7安装nginx并配置前端环境
  • 原文地址:https://www.cnblogs.com/ajanuw/p/11270204.html
Copyright © 2011-2022 走看看