Flutter(二十八)——SQLite数据库

简介: Flutter(二十八)——SQLite数据库

前言


做过手机端应用开发的人,都应该知道SQLite数据库,它是手机端上最老牌,最流行的数据库。使用起来比shared_preferences稍微复杂一点。


前面一篇博文介绍的shared_preferences,我们可以理解为key-value的存储模式,在需要对大量数据进行增删改查操作时,我们就必须使用数据库。比如,在新闻App中,为了用户更好的体验,我们需要存储一些新闻数据,方便用户在离线的模式下,也能体验App的基本功能。


所以为了更好的操作SQLite数据库,Flutter为我们提供了sqflite插件进行数据库的操作,下面我们来详细讲解SQLite的操作方式。


sqflite依赖库


目前与数据库相关,并且使用最广的依赖库就是sqflite。它同时支持Android和IOS两个版本。我们可以直接在Flutter Packages上搜索sqflite,找到下载地址和使用说明。sqflite有以下特性:


(1)支持事务和批处理


(2)支持自动Version管理


(3)支持增删改查的Helpers工具类


(4)支持Android/iOS后台线程的运行


既然我们之前说过sqflite是插件,所以我们开发的时候,需要在Flutter项目中引入这个插件,代码如下:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^0.5.1+1
  sqflite: ^1.1.3//引入代码


sqflite基本用法


sqflite常用的操作方式有8种,代码如下所示:


获取和删除database

_getOrdelete_database()async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    await deleteDatabase(path);
  }


创建数据库与数据表

_create_database() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,value INTEGER,num REAL)');
    });
  }


插入数据

第一种插入数据方法的定义,代码如下:

Future<int> rawInsert(String sql,[List<dynamic> arguments]);

从参数的名称我们可以看出来,第一个参数是一个字符串的sql语句,第二个参数就是传递的List类型的参数,当然前面sql语句需要使用“?”作为占位符,才能传递第二个参数,具体使用代码如下:

_insert_database() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)');
    });
    await database.transaction((txn) async {
      int id1 = await txn.rawInsert(
          'INSERT INTO Demo(name, value, num) VALUES(?, ?)',['Liyuanjing',27]);
      print('inserted1: $id1');
    });
  }


这种是在直接使用sql语句的情况下插入数据,而且参数必须与前面占位符个数一致。


第二种方法在直接使用表名进行插入:

Future<int> insert(String table,Map<String,dynamic> values,{String nullColumnHack,ConflictAlgorithm conflictAlgorithm});

这个方法第一个参数是需要操作的表明,第二个参数是需要插入的数据,通过字段名与对应的值匹配插入,使用代码如下:

_insert_database() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)');
    });
    Map<String,dynamic> values={
      'name':'Liyuanjing',
      'age': 27,
    };
    await database.insert('Demo', values);
}


修改数据

修改操作同样有两种操作方式,第一种方法定义的代码如下:

Future<int> rawUpdate(String sql,[List<dynamic> arguments]);

使用的详细代码如下:

_update_table() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)');
    });
    await database.transaction((txn) async {
      int id1 = await txn.rawUpdate(
          'UPDATE Demo SET name=? WHERE age=?',["Batman",27]);
      print('inserted1: $id1');
    });
  }


第二种方法的代码如下:

Future<int> update(String table,Map<String,dynamic> values,{String where,List<dynamic> whereArgs,ConflictAlgorithm conflictAlgorithm})

使用的代码如下,跟(3)中的第二种方法类似:

_update_table() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)');
    });
    Map<String,dynamic> values={
      'name':'Batman',
    };
    await database.update('Demo', values,where: 'age=?',whereArgs: [27,]);
}


查询数据

同样,查询在sqflite插件中,也有两种操作方式,第一种的方法定义如下:

Future<List<Map<String,dynamic>>> rawQuery(String sql,[List<dynamic> arguments]); 

rawQuery方法的第一个参数为查询用的sql语句,同样用占位符代替参数,第二个参数传入List类型参数来填充sql语句的占位符,占位符与List个数一致,使用代码如下:

_select_database() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)');
    });
    await database.transaction((txn) async {
      List<Map<String,dynamic>> id1 = await txn.rawQuery(
          'SELECT * FROM Demo WHERE age=?',[27]);
    });
  }


接着我们在来看看第二种查询方法的定义,代码如下:

Future<List<Map<String,dynamic>>> query(String table,
{bool distinct,
List<String> columns,
String where,
List<dynamic> whereArgs,
String groupBy,
String having,
String orderBy,
int limit,
int offset});


query方法的第一个参数是操作表名,后边的可选参数依次表示是否去重,查询字段,where的查询子句,where子句的占位符参数值,分组查询子句(groupBy),having子句,orderBy排序子句,limit查询上限条数,查询的偏移位(offset)。基本的使用代码如下:

_select_database() async{
    var databasesPath=await getDatabasesPath();
    String path=join(databasesPath,'demo.db');
    Database database=await openDatabase(path,version:1,onCreate: (Database db,int version) async{
      await db.execute('CREATE TABLE Demo(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)');
    });
    await database.query('Demo',where: 'age=?',whereArgs: [27,]);
}


删除数据

删除数据也分为两种分别是物理删除和逻辑删除。物理删除指的是操作真实的数据库并实现删除操作,而逻辑删除指的是通过update语句修改数据库,并且在查询时过滤掉不符合查询条件的记录,下面我们看一下sqflite里怎样实现逻辑删除。两种操作方式的方法定义代码如下:

Future<int> rawDelete(String sql,[List<dynamic arguments>]);
Future<int> delete(String table,{String where,List<dynamic> whereArgs});

这两种操作方式与上面的增改差基本一致,这里就不在用代码赘述了,除了sql语句不同,其他的一摸一样。


计算总记录数

我们直接看代码:

Sqflite.firstIntValue(await database.rawQuery('Select COUNT(*) FROM Demo'));

关闭数据库

代码很简单,我们这里也直接上代码:

await database.close();

以上八个操作是sqflite的基本操作,除了增删改查稍微复杂一点之外,其他的基本一眼就能掌握,所以本篇终点在于增删改查。

相关文章
|
11天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
80 15
|
1月前
|
存储 SQL 数据库
数据库知识:了解SQLite或其他移动端数据库的使用
【10月更文挑战第22天】本文介绍了SQLite在移动应用开发中的应用,包括其优势、如何在Android中集成SQLite、基本的数据库操作(增删改查)、并发访问和事务处理等。通过示例代码,帮助开发者更好地理解和使用SQLite。此外,还提到了其他移动端数据库的选择。
43 8
|
2月前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
42 4
|
2月前
|
存储 关系型数据库 数据库
轻量级数据库的利器:Python 及其内置 SQLite 简介
轻量级数据库的利器:Python 及其内置 SQLite 简介
70 3
|
2月前
|
应用服务中间件 PHP Apache
PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展...”
PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展...”
|
3月前
|
存储 API 数据库
QML使用Sqlite数据库存储ListModel数据
本文介绍了在QML中使用Sqlite数据库存储ListModel数据的方法,包括如何创建数据库、读取数据、动态添加和删除数据,以及如何在程序启动和退出时与数据库同步数据。
|
3月前
|
数据库 数据库管理
qt对sqlite数据库多线程的操作
本文总结了在Qt中进行SQLite数据库多线程操作时应注意的四个关键问题,包括数据库驱动加载、加锁、数据库的打开与关闭,以及QsqlQuery变量的使用。
218 1
|
2月前
|
存储 缓存 关系型数据库
sqlite 数据库 介绍
sqlite 数据库 介绍
49 0
|
3月前
|
JSON NoSQL 数据库
和SQLite数据库对应的NoSQL数据库:TinyDB的详细使用(python3经典编程案例)
该文章详细介绍了TinyDB这一轻量级NoSQL数据库的使用方法,包括如何在Python3环境中安装、创建数据库、插入数据、查询、更新以及删除记录等操作,并提供了多个编程案例。
154 0
|
4月前
|
SQL 存储 小程序
【教程】navicat配合HTTP通道远程连接SQLite数据库
本文介绍了如何通过 Navicat Premium 工具配合 n_tunnel_sqlite.php 和 HTTP 通道远程连接服务器上的 SQLite 数据库。SQLite 是一种自给自足的、无服务器的 SQL 数据库引擎,由于其端口未对外开放,直接使用 Navicat 进行远程连接不可行。文章详细记录了使用 HTTP 通道实现远程连接的过程,包括定位本地 `ntunnel_sqlite.php` 文件,将其上传至服务器,并通过 Navicat 配置 HTTP 通道连接 SQLite 数据库的具体步骤。
219 0
【教程】navicat配合HTTP通道远程连接SQLite数据库