如何使用SQFlite插件从Flutter中的SQLite数据库查询数据?
我最近一直在努力学习这一点,因此,我在下面添加我的答案,以帮助我学习,并作为将来其他人的快速参考。
打开pubspec.yaml
并在依赖项部分中添加以下行:
sqflite: ^1.0.0 path_provider: ^0.4.1
该sqflite
是SQFlite当然插件和path_provider
将帮助我们在Android和iPhone用户目录。您可以在此处查看最新的版本号:sqflite和path_provider。
我在单例类中保持对数据库的全局引用。这将防止并发问题和数据泄漏。您也可以在此处添加用于访问数据库的辅助方法(例如查询)。
创建一个名为database_helper.dart的新文件,并粘贴以下代码:
import 'dart:io' show Directory; import 'package:path/path.dart' show join; import 'package:sqflite/sqflite.dart'; import 'package:path_provider/path_provider.dart' show getApplicationDocumentsDirectory; class DatabaseHelper { static final _databaseName = "MyDatabase.db"; static final _databaseVersion = 1; static final table = 'my_table'; static final columnId = '_id'; static final columnName = 'name'; static final columnAge = 'age'; // make this a singleton class DatabaseHelper._privateConstructor(); static final DatabaseHelper instance = DatabaseHelper._privateConstructor(); // only have a single app-wide reference to the database static Database _database; Futureget database async { if (_database != null) return _database; // lazily instantiate the db the first time it is accessed _database = await _initDatabase(); return _database; } // this opens the database (and creates it if it doesn't exist) _initDatabase() async { Directory documentsDirectory = await getApplicationDocumentsDirectory(); String path = join(documentsDirectory.path, _databaseName); return await openDatabase(path, version: _databaseVersion, onCreate: _onCreate); } // SQL code to create the database table Future _onCreate(Database db, int version) async { await db.execute(''' CREATE TABLE $table ( $columnId INTEGER PRIMARY KEY, $columnName TEXT NOT NULL, $columnAge INTEGER NOT NULL ) '''); // prepopulate a few rows (consider using a transaction) await db.rawInsert('INSERT INTO $table ($columnName, $columnAge) VALUES("Bob", 23)'); await db.rawInsert('INSERT INTO $table ($columnName, $columnAge) VALUES("Mary", 32)'); await db.rawInsert('INSERT INTO $table ($columnName, $columnAge) VALUES("Susan", 12)'); } }
请注意,创建数据库时,我会预先填充几行。这样,我们就可以在下面的查询示例中使用某些东西。
查询数据我们将使用异步方法进行查询,因为数据库操作可能会很昂贵。
要执行a SELECT *
并返回表中的所有内容,您只需传入表名即可。
_query() async { // get a reference to the database Database db = await DatabaseHelper.instance.database; // get all rows List
我们可以为参数传递参数,where
以选择满足我们条件的特定行。在此示例中,我们将查询ID为的行1
。
_query() async { // get a reference to the database Database db = await DatabaseHelper.instance.database; // get single row ListcolumnsToSelect = [ DatabaseHelper.columnId, DatabaseHelper.columnName, DatabaseHelper.columnAge, ]; String whereString = '${DatabaseHelper.columnId} = ?'; int rowId = 1; List whereArguments = [rowId]; List
whereArguments
列表中的项目将代替?
中的whereString
。在这种情况下,只有一个,?
所以whereArguments
只有一个。如果有两个?
(例如整数和字符串),则列表中将有两个项目。
如果您更喜欢SQL代码本身的熟悉性或灵活性,则可以进行原始查询。在这个例子中,我们将选择其任意行name
列'Mary'
。
_query() async { // get a reference to the database Database db = await DatabaseHelper.instance.database; // raw query List
确保使用通过?
字符串替换的数据绑定。这将防止SQL注入攻击。
如果您在另一个文件中(例如main.dart)DatabaseHelper
,sqflite
则必须导入该类。
SQFlite插件使用Map
来将列名映射到每一行中的数据。
补充代码
为了方便复制和粘贴,以下是的布局代码main.dart
:
import 'package:flutter/material.dart'; // I called my project 'flutter_database_operations'. You can update for yours. import 'package:flutter_database_operations/database_helper.dart'; import 'package:sqflite/sqflite.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'SQFlite Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('sqflite'), ), body: RaisedButton( child: Text('query', style: TextStyle(fontSize: 20),), onPressed: () {_query();}, ), ); } _query() async { // get a reference to the database Database db = await DatabaseHelper.instance.database; // get all rows List继续
这篇文章是我之前的文章的发展:Flutter中的Simple SQFlite数据库示例。有关其他SQL操作和建议,请参阅该帖子。