Как сделать запрос к базе данных с помощью SQFlite во Flutter - PullRequest
0 голосов
/ 16 января 2019

Как вы запрашиваете данные из базы данных SQLite во Flutter, используя плагин SQFlite?

Я недавно работал над этим, поэтому я добавляю свой ответ ниже, чтобы помочь мне учиться, а также каккраткий справочник для других в будущем.

1 Ответ

0 голосов
/ 16 января 2019

Добавьте зависимости

Откройте pubspec.yaml и в разделе зависимостей добавьте следующие строки:

sqflite: ^1.0.0
path_provider: ^0.4.1

sqflite - это плагин SQFlite дляКонечно, и path_provider поможет нам получить каталог пользователей на Android и iPhone.Вы можете проверить самые последние номера версий здесь: sqflite и path_provider .

Создать вспомогательный класс базы данных

I'mхранение глобальной ссылки на базу данных в одноэлементном классе.Это предотвратит проблемы параллелизма и утечки данных.Здесь вы также можете добавить вспомогательные методы (например, запрос) для доступа к базе данных.

Создайте новый файл с именем 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;
  Future<Database> get 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)');
  }
}

Обратите внимание, что при создании базы данных я предварительно заполнил несколько строк,Это связано с тем, что в приведенных ниже примерах запросов нам есть над чем работать.

Запрос данных

Мы будем использовать асинхронный метод для выполнения нашего запроса, поскольку операции с базами данных могут быть дорогими.

Получить все строки

Чтобы сделать SELECT * и вернуть все в таблице, вы просто передаете имя таблицы.

  _query() async {

    // get a reference to the database
    Database db = await DatabaseHelper.instance.database;

    // get all rows
    List<Map> result = await db.query(DatabaseHelper.table);

    // print the results
    result.forEach((row) => print(row));
    // {_id: 1, name: Bob, age: 23}
    // {_id: 2, name: Mary, age: 32}
    // {_id: 3, name: Susan, age: 12}
  }

Получить одну строку

Мы можем передать аргумент для параметра where, чтобы выбрать конкретные строки, которые соответствуют нашим критериям.В этом примере мы запросим строку с идентификатором 1.

  _query() async {

    // get a reference to the database
    Database db = await DatabaseHelper.instance.database;

    // get single row
    List<String> columnsToSelect = [
      DatabaseHelper.columnId,
      DatabaseHelper.columnName,
      DatabaseHelper.columnAge,
    ];
    String whereString = '${DatabaseHelper.columnId} = ?';
    int rowId = 1;
    List<dynamic> whereArguments = [rowId];
    List<Map> result = await db.query(
        DatabaseHelper.table,
        columns: columnsToSelect,
        where: whereString,
        whereArgs: whereArguments);

    // print the results
    result.forEach((row) => print(row));
    // {_id: 1, name: Bob, age: 23}
  }

Элементы в списке whereArguments заменяются вместо ? s в whereString.В этом случае был только один ?, поэтому у whereArguments был только один предмет.Если бы было два ? с (например, целое число и строка), то в списке было бы два элемента.

Необработанный запрос

Если вы предпочитаете знакомство или гибкостьСам код SQL, вы можете сделать необработанный запрос.В этом примере мы выберем любую строку, чей столбец name равен 'Mary'.

  _query() async {

    // get a reference to the database
    Database db = await DatabaseHelper.instance.database;

    // raw query
    List<Map> result = await db.rawQuery('SELECT * FROM my_table WHERE name=?', ['Mary']);

    // print the results
    result.forEach((row) => print(row));
    // {_id: 2, name: Mary, age: 32}
  }

Обязательно используйте привязку данных с использованием ? замены строк.Это защитит от атак с использованием SQL-инъекций.

Примечания

  • Вам придется импортировать класс DatabaseHelper и sqflite, если вы находитесь в другом файле (например, main.dart)..
  • Плагин SQFlite использует Map<String, dynamic> для сопоставления имен столбцов с данными в каждой строке.

Дополнительный код

enter image description here

Для удобства копирования и вставки приведен код макета для 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<Map> result = await db.query(DatabaseHelper.table);

    // get single row
    //List<Map> result = await db.query(DatabaseHelper.table,
    //    columns: [DatabaseHelper.columnId, DatabaseHelper.columnName, DatabaseHelper.columnAge],
    //    where: '${DatabaseHelper.columnId} = ?',
    //    whereArgs: [1]);


    // raw query
    //List<Map> result = await db.rawQuery('SELECT * FROM my_table WHERE name=?', ['Mary']);

    // get each row in the result list and print it
    result.forEach((row) => print(row));
  }
}

Продолжение

...