install

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

lib\db\moor.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);
}

lib\store\main\main.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();

lib\main.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);
},
),
);
}
}

Flutter: moor_flutter库,简化sqlite操作的更多相关文章

  1. [Android新手区] SQLite 操作详解--SQL语法

    该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...

  2. Sqlite操作帮助类

      sqlite帮助类 using System; using System.Collections.Generic; using System.Linq; using System.Text; us ...

  3. 基于Struts2框架实现登录案例 之 使用Struts2标签库简化表单+继承ActionSupport完成输入交验

    一,使用Struts2标签库简化表单 在文章[基于Struts2框架实现登录案例]的基础上,通过使用Struts标签库可以简化登录页面login2.jsp <%@ page language=& ...

  4. 【小结】有关mysql扩展库和mysqli扩展库的crud操作封装

    现阶段php如果要操作mysql数据库 php给我们提供了3套库 1.mysql扩展库   面向过程操作 2.mysqli扩展库  面向对象操作和面向过程操作并存  安全性和效率高于mysql扩展库 ...

  5. 在ASP.NET Core中使用AOP来简化缓存操作

    前言 关于缓存的使用,相信大家都是熟悉的不能再熟悉了,简单来说就是下面一句话. 优先从缓存中取数据,缓存中取不到再去数据库中取,取到了在扔进缓存中去. 然后我们就会看到项目中有类似这样的代码了. pu ...

  6. 通过数组和枚举简化GPIO操作编码(转)

    源: 通过数组和枚举简化GPIO操作编码

  7. 如何利用反射简化Servlet操作

    如何利用反射简化Servlet操作   一.反射的实现 新建类BaseServlet,继承HttpServlet(不需要在web.xml文件中配置) 1.在doPost()方法中处理请求乱码,并调用d ...

  8. 封装CoreGraphics的API简化绘图操作

    封装CoreGraphics的API简化绘图操作 效果 说明 1. 将CoreGraphics的API接口抽象为对象,让绘图变得简单易懂 2. 简化常用的绘制操作 3. 源码长期更新 源码 https ...

  9. php mysqli扩展库之预处理操作

    分享下php使用mysqli扩展库进行预处理操作的二个例子,有意研究mysqli用法的朋友,可以参考学习下,一定会有所帮助的. 例1.使用mysqli扩展库的预处理技术 mysqli stmt 向数据 ...

随机推荐

  1. Shiro中Subject对象的创建与绑定流程分析

    我们在平常使用Shrio进行身份认证时,经常通过获取Subject 对象中保存的Session.Principal等信息,来获取认证用户的信息,也就是说Shiro会把认证后的用户信息保存在Subjec ...

  2. SpringMVC听课笔记(十四:异常处理)

    1. SpringMVC通过HandlerExceptionResolver处理程序的异常,包括Handler映射,数据绑定以及目标方法执行时发生的异常 2.SpringMVC提供的HandlerEx ...

  3. Excel 如何实现以万为单位 保留两位小数 且不四舍五入

    数据科学交流群,群号:189158789,欢迎各位对数据科学感兴趣的小伙伴的加入! =TEXT(INT(I18/100)*1000,"0!.00,万") 将I18替换成你要转化的单 ...

  4. Docker综述

    Docker综述 1.Docker是干什么的? 2.Docker的核心:镜像.容器.仓库 2.1 容器与虚拟机的区别 2.2 仓库 Docker作用 3.Docker的使用 1.Docker是干什么的 ...

  5. SpringMVC 中 @ControllerAdvice 注解

    SpringMVC 中 @ControllerAdvice 注解 1.@ControllerAdvice 1.1 全局异常处理 1.2 全局数据绑定 1.3 全局数据预处理 原文地址: 江南一点雨:S ...

  6. Golang之如何(优雅的)比较两个未知结构的json

    这是之前遇到的一道面试题,后来也确实在工作中实际遇到了.于是记录一下,如何(优雅的)比较两个未知结构的json. 假设,现在有两个简单的json文件. { "id":1, &quo ...

  7. 25.sshd和scp

    1.配置sshd服务 想要使用 SSH 协议来远程管理Linux 系统,则需要部署配置sshd 服务程序.sshd 是基于SSH协议开发的一款远程管理服务程序.   sshd 服务的配置信息保存在/e ...

  8. SANGFOR AC配置AD域单点登录(一)----AC侧配置

    一.需求 1. AD域单点登录适用于客户内网已有AD域统一管理内网用户,部署AC后,希望AC和AD域结合实现平滑认证.即终端PC开机通过域帐号登录AD域后自动通过AC认证上网,无需再次人为通过AC认证 ...

  9. 开发环境管理利器Vagrant

    引言 不知道你是否经历过,开发环境与生产环境不一致.Windows开发和Linux上的包效果不一样.在我这运行时好的啊 等等等问题,那有没有解决方法呢? 答案就是Vagrant.Docker 1.简介 ...

  10. P1280 尼克的任务(DP)

    题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成. 尼克的一个工作日为N分钟,从第一分钟开始 ...