前言
我是以一個大型專案的架構去寫,所以會比較複雜,如果只是要看速成版,可以直接參考官方文件
Sqflite是什麼?SQLite又是什麼?
- SQLite 是一種輕量級的、嵌入式的關聯型資料庫管理系統,適合在移動應用中使用,因為它不需要單獨的服務器進程。iOS 和 Android 都內建了 SQLite 支持。
- Sqflite 是一個用於 Flutter 的插件,封裝了對 SQLite 的操作,使得開發者可以在 Flutter 應用中方便地使用 SQLite 資料庫,而無需手動編寫原生代碼來處理資料庫操作。
- iOS 操作系統本身包含了 SQLite 資料庫,因此APP要做到資料存取,就是使用Flutter的Sqflit插件來存取SQLite資料庫的資料
- Flutter的Sqflite插件來操作SQLite
以下是操作的筆記
檔案架構
因為我是先用DhiWise產生的資料,所以部分沿用他的架構
我沒有列出所有檔案架構,只是紀錄和資料存取有關的架構
- lib
- database
- database_helper.dart
- entities
- xxx_entity.dart
- …
- services
- xxx_service.dart
- …
- entities
- database_helper.dart
- presentation
- models
- widgets
- provider
- database
撰寫程式碼
步驟1:安裝插件
除了安裝Sqflite插件還會安裝Path插件
Path 插件是一個處理路徑的 Dart 庫,能支援跨平台的路徑操作
使用Path插件能避免遇到在某些平台存取不到資料庫路徑
- 網路搜尋插件名稱找到合適的版本
dependencies: sqflite: ^2.3.1+1 path: ^1.9.0
- 終端機輸入flutter pub get,安裝依賴
步驟2:創建 database_helper
- 這個檔案主要功能如下
- 建立資料庫的連接database 屬性用於建立並返回資料庫的連接。如果 _database 已經初始化,則直接返回;否則,呼叫 _initDb 方法來初始化。
- 初始化資料庫
- _initDb 方法用於創建資料庫,並指定數據庫的路徑。
- getDatabasesPath() 方法獲取設備上的數據庫儲存路徑。
- openDatabase 創建或打開一個名為 me_time_db.db 的資料庫,並執行 CREATE TABLE 語句來建立 tasks 資料表。
- 建立資料表
- 我的範例是Task,然後我只設計3個欄位:id, name, description
- 程式碼如下
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = DatabaseHelper._internal();
static Database? _database;
factory DatabaseHelper() {
return _instance;
}
DatabaseHelper._internal();
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDb();
return _database!;
}
Future<Database> _initDb() async {
String path = join(await getDatabasesPath(), 'database_name_db.db');
print('Database path: $path');
return await openDatabase(
path,
version: 3,
onCreate: (db, version) async {
await db.execute(
'''
CREATE TABLE tasks (
task_id TEXT PRIMARY KEY,
name TEXT,
description TEXT,
'''
);
},
);
}
}
步驟3:建立存取的Model – Entity
class TaskEntity {
final String taskId;
final String? name;
final String? description;
TaskEntity({
required this.taskId,
required this.name,
required this.description,
});
factory TaskEntity.fromJson(Map<String, dynamic> json) {
return TaskEntity(
taskId: json['task_id'],
name: json['name'],
description: json['description'],
);
}
Map<String, dynamic> toJson() {
return {
'task_id': taskId,
'name': name,
'description': description,
};
}
}
步驟4:建立存取資料表資料的方法 – Sevice
import 'package:me_time/database/entities/task_entity.dart';
import 'package:sqflite/sqflite.dart';
import '../database_helper.dart';
class TaskService {
static final TaskService _instance = TaskService._internal();
factory TaskService() => _instance;
TaskService._internal();
Future<Database> get _database async {
return await DatabaseHelper().database;
}
Future<List<TaskEntity>> getTasks() async {
final db = await _database;
final List<Map<String, dynamic>> maps = await db.query('tasks');
return List.generate(maps.length, (i) {
return TaskEntity(
taskId: maps[i]['task_id'],
name: maps[i]['name'],
description: maps[i]['description'],
);
});
}
Future<TaskEntity?> getTaskById(String taskId) async {
final db = await _database;
final List<Map<String, dynamic>> maps = await db.query(
'tasks',
where: 'task_id = ?',
whereArgs: [taskId],
);
if (maps.isNotEmpty) {
return TaskEntity.fromJson(maps.first);
}
return null;
}
Future<int> addTask(TaskEntity task) async {
final db = await _database;
return await db.insert(
'tasks',
task.toJson(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<void> updateTask(TaskEntity updatedTask) async {
final db = await _database;
await db.update(
'tasks',
updatedTask.toJson(),
where: 'task_id = ?',
whereArgs: [updatedTask.taskId],
);
}
Future<void> deleteTask(String taskId) async {
final db = await _database;
await db.delete(
'tasks',
where: 'task_id = ?',
whereArgs: [taskId],
);
}
Future<List<TaskEntity>> getAllTasks() async {
return await getTasks();
}
}
如何直接查看到SQLite資料庫
開發ios app時,使用模擬器去做測試,想要查看模擬器中的SQLite資料庫時…
- 首先你會需要先取得資料庫的路徑前面在database_helper時有寫一段,這段會print出路徑
Future<Database> _initDb() async { String path = join(await getDatabasesPath(), 'me_time_db.db'); print('Database path: $path');
可能會得出這樣的路徑/Users/你的用戶名/Library/Developer/CoreSimulator/Devices/模擬器ID/data/Containers/Data/Application/應用ID/Documents/ - 使用 Finder 前往該路徑
- 打開 Finder,按 Cmd + Shift + G 打開「前往文件夾」對話框。
- 將資料庫路徑粘貼進去並按 Enter。這樣會直接打開該文件夾,你應該能夠看到 database_name_db.db
- 使用 SQLite 查看工具
- 我是使用Table Plus,這款資料庫管理工具,介面簡潔,功能齊全,免費版就很夠用,而且支援很多資料庫,他的備份機制也很好用
- 直接到Table Plus官網下載Download for Mac,下載完就可以直接對著database_name_db.db點兩下開啟
- 後面就是工程師在操作資料庫的概念了,我就不贅述