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的基本操作,除了增删改查稍微复杂一点之外,其他的基本一眼就能掌握,所以本篇终点在于增删改查。

相关文章
|
29天前
|
API 数据库 C语言
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
169 0
|
2月前
|
存储 监控 安全
内网屏幕监控软件的数据存储与管理:使用SQLite数据库保存监控记录和配置信息
在当今数字化时代,安全和监控在企业和组织中变得至关重要。内网屏幕监控软件作为一种关键工具,帮助组织监视员工的活动并确保信息安全。这种软件不仅需要高效地记录和管理监控数据,还需要能够方便地进行配置和调整。本文将讨论如何使用SQLite数据库来保存监控记录和配置信息,并介绍如何通过自动化机制将监控到的数据提交到指定网站。
160 2
|
11天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。
|
16天前
|
关系型数据库 MySQL 数据库连接
Python+SQLite数据库实现服务端高并发写入
Python中使用SQLite内存模式实现高并发写入:创建内存数据库连接,建立表格,通过多线程并发写入数据。虽然能避免数据竞争,但由于SQLite内存模式采用锁机制,可能在高并发时引发性能瓶颈。若需更高性能,可选择MySQL或PostgreSQL。
19 0
|
1月前
|
关系型数据库 数据库 C++
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
|
1月前
|
存储 SQL 数据库
django如何连接sqlite数据库?
django如何连接sqlite数据库?
43 0
|
2月前
|
SQL 数据库管理
sqlite语句order by两个字段同时排序处理
sqlite语句order by两个字段同时排序处理
21 0
|
2月前
|
SQL 关系型数据库 MySQL
Python中的数据库操作:SQLite与MySQL的连接
Python中的数据库操作:SQLite与MySQL的连接
122 0
|
2月前
|
SQL 存储 数据库
艺术型轻量级数据库 --Sqlite
艺术型轻量级数据库 --Sqlite
|
3月前
|
SQL Dart 数据库
Flutter笔记: 在Flutter应用中使用SQLite数据库
Flutter笔记: 在Flutter应用中使用SQLite数据库
188 0