Flutter学习之sqfllite使用。

646 阅读2分钟

关于sqfllite使用 需要引入的插件,版本切换为最新版本

#sqlist
sqflite: ^2.0.2+1
#路径管理
path_provider: ^2.0.9

封装

我把他封装成了一个类WXSqliteManage,使用方法在下面。

我创建的每张表里只有两个字段

IdJSON
唯一标识json字符串
import 'dart:async';
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:convert' as convert;
class WXSqliteManage  {
  static var self = WXSqliteManage();
  static const wechatListTabbalName = 'wechat_list';
  static const DBName = 'FlutterWechat.db';
  var databasesPath = getDatabasesPath();
  Database? database;
  
  ///必调方法
  initDatabase() async{
    var path = await self.getPath(DBName);
    database = await openDatabase(path);
  }

  Future<String> getPath(String dbName) async{
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String path = join(appDocDir.path, dbName);
    return path;
  }

  ///创建DB(数据库)
  Future<String> createNewDB(String dbName) async {
    String path = await getPath(dbName);
    ///判断是否存在
    if (await Directory(dirname(path)).exists()) {
      ///如果存在就删除掉,这里只是临时这样处理,实际要根据业务需求.
      // await deleteDatabase(path);
      print('DB已经存在');
    }else{
      print('DB不存在');
      try{
        await Directory(path).create(recursive: true);
        print('DB创建成功');
      }catch(error){
        ///这里如果创建时失败要添加日志
        print('DB创建失败');
        print(error);
      }
    }
    return path;
  }

  createTabbel(String tableName) async{
    if (database == null) {
      var path = await getPath(DBName);
      database = await openDatabase(path);
      await initDatabase();
    }

    bool isTableExit = await isTableExits(tableName);

    if (!isTableExit){
      var batch = database?.batch();
      batch?.execute('''
  CREATE TABLE $tableName (
  Id TEXT PRIMARY KEY, 
  JSON TEXT)
  ''');
      batch?.commit();
    }
  }

  ///增
  addData(String tableName,Map<String, Object?> values, String id) async {
    Map<String, dynamic> tempMap = {};
    tempMap['id'] = id;
    tempMap['json'] = convert.jsonEncode(values);
    if (database == null) {
      await initDatabase();
    }
    ///添加数据如果重复就取代
    int? count = await database?.insert(tableName, tempMap, conflictAlgorithm: ConflictAlgorithm.replace);
    var result = (count ?? 0) > 0 ? '成功':'失败';
    print('------$tableName新增$result------');
  }
  ///删
  deleteData(String tableName, String idName, String id) async{
    if (database == null) {
      await initDatabase();
    }
    ///count > 0说明删除成功
    int? count = await database?.delete(tableName, where: '$idName = ?', whereArgs: [id]);
    var result = (count ?? 0) > 0 ? '成功':'失败';
    print('------$tableName删除$result------');
  }
  ///改
  update(String tabbalName,
      String idName,
      String id,
      Map<String, Object?> values) async{
    if (database == null) {
      await initDatabase();
    }
    int? count = await database?.update(tabbalName, values, where: '$idName = ?', whereArgs: [id]);
    var result = (count ?? 0) > 0 ? '成功':'失败';
    print('------$tabbalName修改$result------');
  }
  ///查
  Future<List<Map>> queryData(String tableName, {String? id}) async{
    if (database == null) {
      await initDatabase();
    }
    List<Map> list;
    if (id == null){
      list = await database?.query(tableName) ?? [];
    }else {
      list = await database?.query(tableName,where: 'Id = ?', whereArgs: [id]) ?? [];
    }
    return list;
  }

  //判断表是否存在
  isTableExits(String tableName) async {
    if (database == null) {
      await initDatabase();
    }
    //内建表sqlite_master
    var sql ="SELECT * FROM sqlite_master WHERE TYPE = 'table' AND NAME = '$tableName'";
    var res = await database?.rawQuery(sql);
    var returnRes = res!=null && res.length > 0;
    return returnRes;
  }


}

使用:

初始化

void main() async {
  await createTabbal();
  runApp(const MyApp());

}
createTabbal() async{
  WidgetsFlutterBinding.ensureInitialized();
  WXSqliteManage.self;
  String path = await WXSqliteManage.self.getPath(WXSqliteManage.DBName);
  bool exists = await Directory(dirname(path)).exists();
  print('createTabbal==$exists path==$path' );
  print('-----');
  await WXSqliteManage.self.createNewDB(WXSqliteManage.DBName);
  await WXSqliteManage.self.createTabbel(WXSqliteManage.wechatListTabbalName);
}

///三个参数分别是 表名,json数据,唯一id
WXSqliteManage.self.addData(WXSqliteManage.wechatListTabbalName, tempModel.toJson(), tempModel.idstr);

///传入表名以及唯一的id删除数据
WXSqliteManage.self.deleteData(WXSqliteManage.wechatListTabbalName, _dataSource[index].idstr);

///三个参数分别是 表名,新数据,唯一标识
WXSqliteManage.self.update(tabbalName, values, id)

查所有

WXSqliteManage.self.queryData(WXSqliteManage.wechatListTabbalName);

查单个

WXSqliteManage.self.queryData(WXSqliteManage.wechatListTabbalName, idid)

开发过程中遇到的问题。

在main()内部调用初始化数据库时会报错。

在初始化前添加一下代码

WidgetsFlutterBinding.ensureInitialized();

还有就是上面封装的代码中,一定要先初始化数据库(也就是创建db文件),然后再创建table。两步缺一不可。

json转字符串 不可以用 dic.toString() 因为他会去掉"号。

解决方法: 引入头文件

import 'dart:convert' as convert;

使用:

///json转字符串
convert.jsonEncode(values)
///字符串转json
convert.jsonDecode(jsonStr)