Flutter 本地数据库sqflite实战操作

Flutter 本地数据库sqflite实战操作

通过本文章将带你了解sqflite如何使用并管理,注意要学习本功能、要具备一定的sql数据库操作的基础知识!

知识点:

  • 本地化列表数据
  • 本地化列表详情数据
  • sqflite 本地化数据库增删改查操作
一、安装sqflite

https://pub.flutter-io.cn/packages/sqflite

二、创建Db数据库文件夹,创建Db文件

文件夹路径:Lib/Db/StepTasksDb/StepTasksDb.dart

三、编辑Db文件

StepTasksDb.dart全部代码

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

// 定义数据库Mock模型
final String tableName = 'step_task_table';                       // 数据库名称
final String columnId = '_id';                                    // 索引id
final String columnType = 'step_listType';                        // 列表类型
final String columnStepListData = 'step_listData';                // 列表数据
final String columnStepDataDetails = 'step_status';               // 列表详情数据


// 定义模板模型类
class StepTasks {
  int id;
  String stepListType;                                            // 列表类型
  String stepListData;                                            // 列表数据
  String stepDataDetails;                                         // 详情数据

  StepTasks({this.id, this.stepListType, this.stepListData, this.stepDataDetails});

  // 模型转Map数据使用
  Map<String, Object> toMap() {
    var map = <String ,Object>{
      columnType:stepListType,
      columnStepListData:stepListData,
      columnStepDataDetails:stepDataDetails
    };
    if (id != null) {
      map[columnId] = id;
    }
    return map;
  }

  // 模型数据传入类中
  StepTasks.fromMap(Map<String, Object> map){
    id = map[columnId];
    stepListType = map[columnType];
    stepListData = map[columnStepListData];
    stepDataDetails = map[columnStepDataDetails];
  }
}

// 定义数据库
class StepTasksDb {
  Database db;
  
  // 初始化数据库
  Future<String> initDatabase() async {
    // 获取本地存储数据库路径
    var databasesPath = await getDatabasesPath();
    // 创建数据库db文件
    String path = join(databasesPath, 'stepTasks.db');
    return path;
  }

  // 打开并创建表
  Future open(String path) async {
    print('------------------打开并创建表<StepTasksDb>------------------');
    db = await openDatabase(path, version:1, onCreate:(Database db, int version) async {
      await db.execute('''
        create table $tableName (
          $columnId integer primary key autoincrement,
          $columnType text ,
          $columnStepListData text ,
          $columnStepDataDetails text
        )
      ''');
    });
  }

  // 添加数据
  Future<StepTasks> insert(StepTasks data) async {
    data.id = await db.insert(tableName, data.toMap());
    return data;
  }

  // 获取数据(根据type条件查询)
  Future<List> getData({type = ''}) async {
    List<Map> maps = [];
    maps = await db.query(tableName, columns:[columnId, columnType, columnStepListData, columnStepDataDetails], where: '$columnType = ?', whereArgs: [type]);

    if(maps ==null || maps.length == 0){
      return [];
    }

    List list = [];

    for(int i = 0; i<maps.length; i++){
      list.add(maps[i]);
    }

    return list;
  }


  // 修改数据(通过id匹配修改整个数据)
  Future<int> update(StepTasks data) async {
    return await db.update(tableName, data.toMap(), where: '$columnId = ?', whereArgs: [data.id]);
  }

  // 删除数据(通过id匹配删除数据)
  Future<int> delete(int id) async {
    return await db.delete(tableName, where:'$columnId = ?', whereArgs:[id]);
  }

  // 关闭此表的链接
  Future close() async => db.close();
}
四、使用创建的数据库文件

注意:
首先安装网络监听插件:connectivity,虽然本插件已经停止更新了,但是在Pub官方文档也有新的插件替代了旧插件,大家可以凭个人需求来,这里不强求用什么插件,只需要达到网络监听效果即可。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'TestDb_Flutter/Db/StepTasksDb/StepTasksDb.dart';

class TestDbPage extends StatefulWidget {

  @override
  State<TestDbPage> createState() => _TestDbPageState();
}

class _TestDbPageState extends State<TestDbPage> {

  var listData = [];
  var _storageListData = [];          // 存储本地数据
  List cacheSelectList = [];          // 存储需要缓存的数据
  var networkStatus = -1;			  // -1:没有网络 1:wifi  2:4G
  StepTasksDb _stepTaskDb = StepTasksDb();

  @override
  void initState() { 
    super.initState();
    _initDatabase();
  }
  
 // 打开数据库
  Future _initDatabase() async {
    String path = await _stepTaskDb.initDatabase();
    // await File(path).delete();       // 删除表
    await _stepTaskDb.open(path);       // 打开表
    _getListData();
  }

 // 网络请求数据
 Future _getListData() async {
 	await _getStorageData();
 	if(networkStatus == 1){
 		var res = await api.request('https://xxx.xxxx/api');
		setState((){listData = res['data']})
		return res;
 	}else{
 		// 没有网络的话
	    setState(() {
	      _listData = _storageListData;
	    });
	    return _storageListData;
 	}
	
 }

 // 获取本地数据
 Future _getStorageData() async {
    var data = await _stepTaskDb.getData(type: 'process');   
    setState(() {
      _storageListData = data;           // 先赋值一次 以便添加时使用
    });
  }
  
  @override
  void dispose() {
    // 关闭数据库
    _stepTaskDb.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: listData.length,
      itemBuilder: (context, index){
        return InkWell(
        	child:Container(child:Text(listData[index]['title']));
        	onTap:(){
        	      // 创建要存储本地的数据
        		  var dataBase = {
                    'step_listData': json.encode(listData[index]),
                  };
                  // 请求详情的参数
                  var params = {id:'xxx'};
                  var res = await api.request('https://xxx.xxxx/api', formData: params);
				  // 不为空的话,证明拿到了正常数据,将其存储到要存储的数据参数中
                  if(res != null){
                    dataBase['assets_listDetails'] = json.encode(res['data']);
                  }
        		  // 进行本地缓存
                  var db_res = await _stepTaskDb.insert(StepTasks(stepListType:'process', stepListData:dataBase['step_listData'], stepDataDetails:dataBase['assets_listDetails']));
        	},
        	onLongPress: (){
        			// 只在获取了本地存储的情况下,才能够通过id删除数据
	       	      _stepTaskDb.delete(v['_id']);
	      	},
        );
      },
    );
  }
}

以上代码暂且只介绍了本地化操作的 增删查操作、至于修改操作,则和增操作大体类似,通过传入的本地数据id,来将新的数据替换掉旧的数据即可

例子:

var res = await _stepTaskDb.update(StepTasks(id:v['id'], stepListType:'process', stepListData:dataBase['listData'], stepDataDetails:dataBase['listDetails']));

目前为止,应该将最基本的增删改查操作介绍完了,并且附上了例子,如果不出大问题的话,大家应该可以达到本地化数据的操作,有问题请下方留言联系我~

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 首先,要在 `pubspec.yaml` 中添加 `sqflite` 依赖,然后可以这样做: 1. 在应用的某个地方导入 `sqflite` 和 `path_provider` 库: ```dart import 'package:sqflite/sqflite.dart'; import 'package:path_provider/path_provider.dart'; ``` 2. 调用 `getDatabasesPath()` 函数获取数据库文件的路径: ```dart final String path = await getDatabasesPath(); ``` 3. 使用 `openDatabase()` 函数打开数据库: ```dart final Database database = await openDatabase( path, version: 1, onCreate: (Database db, int version) async { // 在这里可以执行建表之类的初始化操作 }, ); ``` 4. 使用 `database.query()` 方法执行查询,这个方法会返回一个 `List<Map<String, dynamic>>` 类型的结果: ```dart final List<Map<String, dynamic>> maps = await database.query( 'your_table_name', columns: ['column1', 'column2', 'column3'], // 这里指定要查询哪些列 where: 'column1 = ?', // 可以指定 where 条件 whereArgs: ['value1'], // 可以指定 where 参数 ); ``` 5. 在上述查询的结果中,每一个 `Map` 对应了一条查询结果,你可以使用下面的方法将结果转换为实体对象的列表: ```dart final List<YourEntity> entities = maps.map((map) => YourEntity.fromMap(map)).toList(); ``` 其中,`YourEntity` 是你的实体类,`fromMap()` 方法是在实体类中定义的,用来将查询结果的 `Map` 转换为实 ### 回答2: 在Flutter中使用sqflite库来查询数据并将查询结果转换为实体对象的步骤如下: 1. 导入sqflite库:在项目的pubspec.yaml文件中添加sqflite依赖,并执行`flutter packages get`命令下载库文件。 2. 创建数据库帮助类:首先,创建一个继承自`DatabaseHelper`的数据库帮助类。在该类中,需要定义数据库的名称、版本号以及数据表的结构等。同时,还需要实现数据库的打开、创建表和升级的方法。 3. 查询数据并转换为实体对象:在数据查询的方法中,首先使用`await openDatabase`方法打开数据库连接。然后,使用`rawQuery`方法进行数据查询,该方法接收查询语句作为参数,并返回一组符合条件的记录。对于每条记录,可以通过索引获取各个字段的值。进一步,我们可以将这些字段的值传递给实体类的构造方法,从而创建实体对象。最后,将所有的实体对象保存到一个List列表中,并返回列表作为查询结果。 以下是一个示例代码,展示了如何使用sqflite库来查询数据并转换为实体对象的过程: ```dart import 'package:sqflite/sqflite.dart'; class Book { int id; String title; String author; Book({this.id, this.title, this.author}); factory Book.fromMap(Map<String, dynamic> json) => Book( id: json['id'], title: json['title'], author: json['author'], ); } class DatabaseHelper { static final DatabaseHelper _instance = DatabaseHelper.internal(); factory DatabaseHelper() => _instance; Database _db; Future<Database> get db async { if (_db != null) { return _db; } _db = await initDb(); return _db; } Future<Database> initDb() async { // 创建数据库 String databasesPath = await getDatabasesPath(); String path = join(databasesPath, 'my_database.db'); var db = await openDatabase(path, version: 1, onCreate: _onCreate); return db; } void _onCreate(Database db, int version) async { // 创建表 await db.execute( "CREATE TABLE books(id INTEGER PRIMARY KEY, title TEXT, author TEXT)"); } Future<List<Book>> getBooks() async { var dbClient = await db; var result = await dbClient.rawQuery("SELECT * FROM books"); List<Book> books = []; result.forEach((row) { books.add(Book.fromMap(row)); }); return books; } } // 使用方法示例 void main() async { DatabaseHelper db = DatabaseHelper(); List<Book> books = await db.getBooks(); for (var book in books) { print(book.title); } } ``` 在上述代码中,首先定义了一个名为Book的实体类,该类具有id、title和author字段。然后,创建了一个名为DatabaseHelper的数据库帮助类,其中包含了打开数据库、创建表和查询数据的方法。最后,通过调用DatabaseHelper类的getBooks方法,我们可以获取到所有的Book实体对象,并将其遍历打印出来。 这样,我们就完成了使用sqflite库查询数据并转换为实体对象的操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值