iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
自我挑戰組

30天學習flutter系列 第 20

20.flutter的持久化存儲(三)

  • 分享至 

  • xImage
  •  

Sqfite

今天我們來使用sqfite來簡單的存儲我們的todo

添加我們的依賴sqflite and path

dependencies:
  sqflite: ^2.0.0+4
  path: ^1.8.1

簡單的介紹一下sqfite功能

我們來修改我們的todo\lib\models\todo_model.dart

import 'dart:convert';

class TodoModel {
  TodoModel({
    required this.title,
    required this.done,
    required this.date,
  });

  final String title;
  final bool done;
  final String date;

  TodoModel copyWith({
    String? title,
    bool? done,
    String? date,
  }) =>
      TodoModel(
        title: title ?? this.title,
        done: done ?? this.done,
        date: date ?? this.date,
      );

  factory TodoModel.fromJson(String str) => TodoModel.fromMap(json.decode(str));

  String toJson() => json.encode(toMap());

  factory TodoModel.fromMap(Map<String, dynamic> json) => TodoModel(
        title: json["title"],
        done: json["done"] == 1 ? true : false,
        date: json["date"],
      );

  Map<String, dynamic> toMap() => {
        "title": title,
        "done": done,
        "date": date,
      };
}

並且新增我們的Db Provider

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/models/user_model.dart';

class DbProvider {
  static final DbProvider instance = DbProvider._init();
  static Database? _db;

  //o banco de dados sera iniciado na instancia da classe
  DbProvider._init();

  Future<Database> get db async {
    if (_db != null) return _db!;
    _db = await _useDatabase('notes.db');
    return _db!;
  }

  Future<Database> _useDatabase(String filePath) async {
    final dbPath = await getDatabasesPath();

    return await openDatabase(
      join(dbPath, 'todo.db'),
      onCreate: (db, version) {
        return db.execute('''
            create table Todo ( 
              id integer primary key autoincrement, 
              title text not null,
              date text,
              done integer not null
            )
          ''');
      },
      version: 1,
    );
  }

  Future<List<TodoModel>> getTodos() async {
    final db = await instance.db;
    final result = await db.rawQuery('SELECT * FROM Todo');
    // print(result);
    return result.map((i) {
      print(i);
      return TodoModel.fromMap(i);
    }).toList();
  }

  Future addTodo(TodoModel todo) async {
    final db = await instance.db;
    final id = await db.rawInsert(
        'INSERT INTO Todo (Title, Date, Done) VALUES (?,?,?)',
        [todo.title, todo.date, todo.done]);

    print(id);
  }

  //fechar conexao com o banco de dados, funcao nao usada nesse app
  Future close() async {
    final db = await instance.db;
    db.close();
  }
}

修改我們的todo\lib\states\todo_state.dart

import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/db/db_provider.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/Itodo_state.dart';

class TodoState extends StateNotifier<List<TodoModel>> implements ITodoState {
  TodoState(this.ref)
      : _dbProvider = ref.watch(dbProvider),
        super([]);

  final Ref ref;
  final DbProvider _dbProvider;

  @override
  Future<List<TodoModel>> getTodos() async {
    // TODO: implement getTodos
    try {
      await Future.delayed(const Duration(seconds: 1));
      final todos = await _dbProvider.getTodos();
      state = todos;
    } catch (e) {
      throw Exception();
    }

    return state;
  }

  @override
  void addTodo(TodoModel todo) async {
    // TODO: implement addTodo
    try {
      await _dbProvider.addTodo(todo);
      getTodos();
    } catch (e) {
      throw Exception();
    }
    // state = [
    //   ...state,
    //   todo,
    // ];
  }
}

final dbProvider = Provider((ref) => DbProvider.instance);

final todosProvider = StateNotifierProvider<TodoState, List<TodoModel>>((ref) {
  return TodoState(ref);
});

接著,我們來測試一下
https://ithelp.ithome.com.tw/upload/images/20221006/20108931ycucVyrr4l.png
https://ithelp.ithome.com.tw/upload/images/20221006/20108931fdqvRgcx9E.png

console
https://ithelp.ithome.com.tw/upload/images/20221006/20108931umqjzNWrOt.png

Add
https://ithelp.ithome.com.tw/upload/images/20221006/20108931obWwkW7unS.png
https://ithelp.ithome.com.tw/upload/images/20221006/20108931brr1dWjKVe.png

重新啟動後再點擊,能發現狀態還在,我們已經將狀態給存儲在sqlite中了


上一篇
19.flutter的持久化存儲(二)
下一篇
21.flutter的持久化存儲(四)
系列文
30天學習flutter30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言