【Flutter 程式設計入門實戰 30 天】Day 29:Sqflite 資料庫存取

【Flutter 程式設計入門實戰 30 天】線上教學課程目錄 使用 Dart 程式語言,開發 Android 和 iOS APP 應用程式。

哈囉~大家好,我是 KT ,今天實戰第二十九天,KT 將為大家來介紹,Sqflite 資料庫存取。

範例畫面

Sqflite 資料庫存取

當你需要大量資料存在手機端,可以採用 SQLite 資料庫,而 Flutter 會透過 sqflite 這個套件來處理 SQLite 資料庫。

新增加入 sqflite 和 path 套件

最新版號,可以連結至 pub.dev 進行查詢:

dependencies:
  flutter:
    sdk: flutter
  sqflite: 2.0.0
  path_provider: 2.0.2

PS. ^表示與當前大版號一致的版本,〜表示和當前小版號一致的版本。

加入位置實際範例

定義數據模型

定義一個學生的數據模型,裡面共有三個資料欄位,分別是:

  • id:識別欄位,唯一值為整數資料類型
  • name:存放學生名字為字串資料類型
  • score:存放學生成績,為整數資料類型。

student.dart

class Student {
  final int? id;
  final String? name;
  final int? score;

  Student({this.id, this.name, this.score});

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'score': score,
    };
  }
}

DatabaseHelper

DatabaseHelper 負責建立資料庫、資料表、共用的 CRUD 操作

database_helper.dart

import 'dart:io';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

class DatabaseHelper {
  static final _databaseName = "MyDatabase.db";
  static final _databaseVersion = 1;

  static final table = 'my_table';


  //Singleton 單例模式,確保一個類別只有一個實例
  DatabaseHelper._privateConstructor();

  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();


  static Database? _database;

  Future<Database?> get database async {
    if (_database != null) return _database;
    _database = await _initDatabase();
    return _database;
  }

  _initDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, _databaseName);
    return await openDatabase(path,
        version: _databaseVersion, onCreate: _onCreate);
  }

  Future _onCreate(Database db, int version) async {
    await db.execute('''
          CREATE TABLE $table (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            score INTEGER NOT NULL
          )
          ''');
  }


  Future<int> insert(Map<String, dynamic> row) async {
    Database? db = await instance.database;
    return await db!.insert(table, row);
  }


  Future<List<Map<String, dynamic>>> queryAllRows() async {
    Database? db = await instance.database;
    return await db!.query(table);
  }


  Future<int?> queryRowCount() async {
    Database? db = await instance.database;
    return Sqflite.firstIntValue(
        await db!.rawQuery('SELECT COUNT(*) FROM $table'));
  }

  Future<int> update(Map<String, dynamic> row) async {
    Database? db = await instance.database;
    int id = row['id'];
    return await db!.update(table, row, where: 'id = ?', whereArgs: [id]);
  }

  Future<int> delete(int id) async {
    Database? db = await instance.database;
    return await db!.delete(table, where: 'id = ?', whereArgs: [id]);
  }
}

建立處理學生表格資料管理者

student_manager.dart

import 'package:flutter_demo/student.dart';

import 'database_helper.dart';

class StudentManager {
  final dbHelper = DatabaseHelper.instance;

  //Singleton 單例模式,確保一個類別只有一個實例
  StudentManager._privateConstructor();

  static final StudentManager instance = StudentManager._privateConstructor();

  //插入資料
  void insert() async {
    var student = Student(
      name: 'HKT',
      score: 59,
    );

    dbHelper.insert(student.toMap());
    print('--- insert 執行結束---');
  }

  //查詢資料
  void query() async {
    final rows = await dbHelper.queryAllRows();
    print('查詢結果:');
    rows.forEach((row) => print(row));
    print('--- query 執行結束---');
  }

  //更新資料
  void update() async {
    var student = Student(
      id: 1,
      name: 'HKT',
      score: 100,
    );
    dbHelper.update(student.toMap());
    print('--- update 執行結束---');
  }

  //刪除資料
  void delete() async {
    final id = await dbHelper.queryRowCount();
    dbHelper.delete(id!);
    print('--- delete 執行結束---');
  }
}

UI 操作畫面

在畫面加入四顆按鈕,來呼叫新增、查詢、修改、刪除等方法。

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_demo/student_manager.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text('HKT線上教室'),
          ),
          body: HomePage(),
        ));
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          RaisedButton(
            child: Text(
              '新增',
              style: TextStyle(fontSize: 20),
            ),
            onPressed: () {
              StudentManager.instance.insert();
            },
          ),
          RaisedButton(
            child: Text(
              '查詢',
              style: TextStyle(fontSize: 20),
            ),
            onPressed: () {
              StudentManager.instance.query();
            },
          ),
          RaisedButton(
            child: Text(
              '修改',
              style: TextStyle(fontSize: 20),
            ),
            onPressed: () {
              StudentManager.instance.update();
            },
          ),
          RaisedButton(
            child: Text(
              '刪除',
              style: TextStyle(fontSize: 20),
            ),
            onPressed: () {
              StudentManager.instance.delete();
            },
          ),
        ],
      ),
    );
  }
}

運行執行結果

  • 點擊「新增」按鈕
I/flutter (19999): --- insert 執行結束---
  • 點擊「查詢」按鈕
I/flutter (19999): 查詢結果:
I/flutter (19999): {id: 1, name: HKT, score: 59}
I/flutter (19999): --- query 執行結束---
  • 點擊「修改」按鈕
I/flutter (19999): --- update 執行結束---
  • 點擊「查詢」按鈕
I/flutter (19999): {id: 1, name: HKT, score: 100}
I/flutter (19999): --- query 執行結束---
  • 點擊「刪除」按鈕
I/flutter (19999): --- delete 執行結束---
  • 點擊「查詢」按鈕
I/flutter (19999): 查詢結果:
I/flutter (19999): --- query 執行結束---

那今天就介紹到這邊囉~

順帶一提,KT 線上教室,臉書粉絲團,會不定期發佈相關資訊,不想錯過最新資訊,不要忘記來按讚,加追蹤喔!也歡迎大家將這篇文章分享給更多人喔。

我們明天見囉!!!掰掰~

參考資料

HKT 線上教室
http://tw-hkt.blogspot.com/

Background vector created by freepik
https://www.freepik.com

Persist data with SQLite
https://flutter.dev/docs/cookbook/persistence/sqlite

Simple SQFlite database example in Flutter
https://medium.com/@suragch/simple-sqflite-database-example-in-flutter-e56a5aaa3f91