MST

星途 面试题库

面试题:Flutter中SQLite与性能优化及数据安全

在大型Flutter应用中使用SQLite进行离线数据存储时,可能会面临性能和数据安全方面的挑战。请阐述你会从哪些方面进行性能优化(如索引策略、缓存机制等),以及如何保障数据的安全性(如加密、防止SQL注入等)。针对每个方面,给出具体的实现思路或示例代码。
13.0万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

性能优化

  1. 索引策略
    • 实现思路:分析应用中频繁执行的查询语句,为这些查询涉及的列创建索引。例如,如果经常根据某个用户ID查询相关数据,就为用户ID列创建索引。
    • 示例代码
// 创建表时同时创建索引
await database.execute('''
  CREATE TABLE my_table (
    id INTEGER PRIMARY KEY,
    user_id TEXT,
    data TEXT
  )
''');
await database.execute('''
  CREATE INDEX idx_user_id ON my_table (user_id)
''');
  1. 缓存机制
    • 实现思路:在内存中缓存经常访问的数据。可以使用Map来实现简单的缓存,每次查询时先检查缓存中是否有数据,若有则直接返回,否则查询数据库并将结果存入缓存。
    • 示例代码
Map<String, dynamic> cache = {};
Future<dynamic> getData(String key) async {
  if (cache.containsKey(key)) {
    return cache[key];
  }
  var result = await database.query('my_table', where: 'key =?', whereArgs: [key]);
  if (result.isNotEmpty) {
    cache[key] = result.first;
    return result.first;
  }
  return null;
}
  1. 批量操作
    • 实现思路:将多次小的数据库操作合并为一次批量操作,减少数据库I/O次数。例如,插入多条数据时,使用batch方法。
    • 示例代码
var batch = database.batch();
List<Map<String, dynamic>> dataList = [
  {'name': 'John', 'age': 25},
  {'name': 'Jane', 'age': 30}
];
for (var data in dataList) {
  batch.insert('users', data);
}
await batch.commit();

数据安全保障

  1. 加密
    • 实现思路:使用加密库(如pointycastle)对敏感数据进行加密后再存入数据库。读取数据时进行解密。
    • 示例代码
import 'package:pointycastle/export.dart';
import 'package:convert/convert.dart';

// 加密
String encryptData(String data, String key) {
  final keyBytes = hex.decode(key);
  final iv = Uint8List(16);
  final aes = AESFastEngine();
  final blockCipher = PaddedBlockCipher(aes, 'PKCS7');
  final parameters = ParametersWithIV(KeyParameter(keyBytes), iv);
  blockCipher.init(true, parameters);
  final encrypted = blockCipher.process(utf8.encode(data));
  return base64.encode(encrypted);
}

// 解密
String decryptData(String encryptedData, String key) {
  final keyBytes = hex.decode(key);
  final iv = Uint8List(16);
  final aes = AESFastEngine();
  final blockCipher = PaddedBlockCipher(aes, 'PKCS7');
  final parameters = ParametersWithIV(KeyParameter(keyBytes), iv);
  blockCipher.init(false, parameters);
  final decrypted = blockCipher.process(base64.decode(encryptedData));
  return utf8.decode(decrypted);
}
  1. 防止SQL注入
    • 实现思路:在执行查询时,使用参数化查询,而不是直接拼接SQL语句。
    • 示例代码
// 错误示例:可能导致SQL注入
// String userId = "1 OR 1 = 1";
// var result = await database.query('users', where: 'user_id = $userId');

// 正确示例:参数化查询
String userId = "1";
var result = await database.query('users', where: 'user_id =?', whereArgs: [userId]);