一、引言

在Flutter开发里,数据持久化是个很重要的事儿。咱得把数据存下来,这样即使应用关了再打开,之前的数据还能在。今天就来聊聊两个常用的数据持久化方案:SharedPreferences和SQLite,看看啥时候用哪个更合适。

二、SharedPreferences介绍

原理和用途

SharedPreferences就像是一个小盒子,专门用来存一些简单的数据,像用户的设置、偏好啥的。它是键值对的形式,就好比给每个数据都贴上一个标签,用这个标签能轻松找到对应的数据。它操作起来简单,存和取都方便,不过只能存一些简单的数据类型,像字符串、布尔值、整数这些。

示例代码(Dart技术栈)

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

// 定义一个存储和读取数据的类
class SharedPreferencesExample {
  // 存储数据的方法
  static Future<void> saveData() async {
    // 获取SharedPreferences实例
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // 存储一个字符串数据,键为'name',值为'John'
    await prefs.setString('name', 'John');
    // 存储一个布尔值数据,键为'isLoggedIn',值为true
    await prefs.setBool('isLoggedIn', true);
  }

  // 读取数据的方法
  static Future<void> readData() async {
    // 获取SharedPreferences实例
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // 根据键'name'读取存储的字符串数据
    String? name = prefs.getString('name');
    // 根据键'isLoggedIn'读取存储的布尔值数据
    bool? isLoggedIn = prefs.getBool('isLoggedIn');
    print('Name: $name');
    print('Is Logged In: $isLoggedIn');
  }
}

在这个示例里,我们先定义了一个SharedPreferencesExample类,里面有两个方法,一个用来存数据,一个用来读数据。先通过SharedPreferences.getInstance()获取实例,然后用setStringsetBool这些方法存数据,用getStringgetBool这些方法读数据。

优缺点

优点:

  • 简单易用,代码写起来不复杂,新手也能快速上手。
  • 存和取数据速度快,对于简单的数据操作很合适。

缺点:

  • 只能存简单的数据类型,像对象、列表这种复杂的数据就存不了。
  • 不适合存大量的数据,数据多了性能会受影响。

应用场景

  • 存用户的设置,比如是否开启音效、字体大小这些。
  • 存登录状态,判断用户是否已经登录。

注意事项

  • 数据存储是异步的,在操作数据时要注意异步处理,不然可能会出现数据不一致的情况。
  • 数据是明文存储的,要是存敏感数据,得考虑加密问题。

三、SQLite介绍

原理和用途

SQLite是一个轻量级的数据库,它就像一个大仓库,能存各种复杂的数据。它支持SQL语句,通过这些语句可以对数据进行增删改查操作。它适合存大量的数据,像应用里的用户信息、商品信息这些。

示例代码(Dart技术栈)

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

// 定义一个操作SQLite数据库的类
class SQLiteExample {
  static Database? _database;

  // 获取数据库实例
  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB();
    return _database!;
  }

  // 初始化数据库
  Future<Database> _initDB() async {
    String path = join(await getDatabasesPath(), 'example.db');
    return await openDatabase(
      path,
      version: 1,
      onCreate: (db, version) {
        // 创建一个名为'users'的表,包含'id'和'name'两列
        return db.execute(
          'CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT)',
        );
      },
    );
  }

  // 插入数据的方法
  Future<void> insertUser(Map<String, dynamic> user) async {
    final db = await database;
    await db.insert(
      'users',
      user,
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  // 查询数据的方法
  Future<List<Map<String, dynamic>>> getUsers() async {
    final db = await database;
    return await db.query('users');
  }
}

在这个示例里,我们定义了一个SQLiteExample类,里面有几个方法。_initDB方法用来初始化数据库,创建一个名为users的表。insertUser方法用来往表里插入数据,getUsers方法用来查询表中的数据。

优缺点

优点:

  • 能存大量的数据,还能处理复杂的数据关系。
  • 支持SQL语句,操作灵活,可以进行各种复杂的查询。

缺点:

  • 学习成本相对高一些,得懂点SQL语句。
  • 代码写起来比SharedPreferences复杂,要处理数据库的打开、关闭等操作。

应用场景

  • 存应用里的业务数据,像订单信息、商品信息。
  • 做离线缓存,把一些经常用的数据存到本地。

注意事项

  • 数据库操作是异步的,要注意异步处理,避免阻塞UI线程。
  • 数据库版本管理很重要,升级数据库时要处理好数据迁移。

四、选型对比

数据类型和复杂度

如果只是存简单的数据,像用户的设置、偏好,用SharedPreferences就行。要是存复杂的数据,像对象、列表,或者要处理数据之间的关系,那就得用SQLite。

数据量

数据量小的时候,SharedPreferences足够了,操作简单又快。但数据量大了,SharedPreferences性能就不行了,这时候就得用SQLite。

操作复杂度

SharedPreferences操作简单,适合快速开发。SQLite操作复杂一些,需要对数据库有一定的了解。

性能

SharedPreferences读写速度快,但数据量大时性能下降。SQLite在处理大量数据时性能更稳定。

五、总结

SharedPreferences和SQLite都是Flutter里常用的数据持久化方案,各有各的优缺点和适用场景。SharedPreferences简单易用,适合存简单的数据和小数据量。SQLite功能强大,适合存大量的数据和处理复杂的数据关系。在开发时,要根据实际需求来选择合适的方案,这样才能让应用更高效、稳定。