Flutter数据库管理插件sqlcool2的使用

Flutter数据库管理插件sqlcool2的使用

sqlcool2 是一个用于简化数据库操作的 Flutter 插件。它基于 sqflite 库,并提供了简单的 CRUD 操作接口、响应式数据流等功能。

简单的CRUD操作

定义数据库模式

import 'package:sqlcool/sqlcool.dart';

Db db = Db();
// 定义数据库模式
DbTable category = DbTable("category")..varchar("name", unique: true);
DbTable product = DbTable("product")
   ..varchar("name", unique: true)
   ..integer("price")
   ..text("description", nullable: true)
   ..foreignKey("category", onDelete: OnDelete.cascade)
   ..index("name");
List<DbTable> schema = [category, product];

初始化数据库

String dbPath = "db.sqlite"; // 相对于文档目录
try {
  await db.init(path: dbPath, schema: schema);
} catch (e) {
  rethrow;
}

插入数据

final Map<String, String> row = {"name": "My item"};
try {
  int id = await db.insert(table: "category", row: row);
} catch (e) {
  rethrow;
}

查询数据

try {
  List<Map<String, dynamic>> rows = await db.select(
    table: "product",
    limit: 20,
    columns: "id,name",
    where: "name LIKE '%something%'",
    orderBy: "name ASC",
  );
} catch (e) {
  rethrow;
}

更新数据

try {
  int numRowsUpdated = await db.update(table: "category", 
   row: row, where: "id=1");
} catch (e) {
  rethrow;
}

删除数据

try {
  await db.delete(table: "category", where: "id=3");
} catch (e) {
  rethrow;
}

联合查询

try {
  final data = await db.join(
   table: "product",
   columns: "product.name,price,category.name as category_name",
   joinTable: "category",
   joinOn: "product.category=category.id");
} catch (e) {
  rethrow;
}

多表联合查询

try {
  final data = db.mJoin(table: "product", joinsTables: [
   "category",
   "manufacturer"
 ], joinsOn: [
   "product.category=category.id",
   "product.manufacturer=manufacturer.id"
 ]);
} catch (e) {
  rethrow;
}

响应式功能

变更流

数据库变更事件的流可用。灵感来自 RethinkDB。

import 'dart:async';
import 'package:sqlcool/sqlcool.dart';

StreamSubscription changefeed;

changefeed = db.changefeed.listen((change) {
   print("Change in the database:");
   print("Query: ${change.query}");
   if (change.type == DatabaseChange.update) {
     print("${change.value} items updated");
   }
 });
// 结束使用时取消订阅
changefeed.cancel();

响应式选择区块

bloc 会在任何数据库更改时重新构建,因为 reactive 参数设置为 true

import 'package:flutter/material.dart';
import 'package:sqlcool/sqlcool.dart';

class _PageSelectBlocState extends State<PageSelectBloc> {
  SelectBloc bloc;

  @override
  void initState() {
    super.initState();
    this.bloc = SelectBloc(
        table: "items", orderBy: "name", reactive: true);
  }

  @override
  void dispose() {
    bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("My app")),
      body: StreamBuilder<List<Map>>(
          stream: bloc.items,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              // 查询未找到任何内容
              if (snapshot.data.length == 0) {
                return Center(child: const Text("No data"));
              }
              // 查询有结果
              return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {
                    var item = snapshot.data[index];
                    return ListTile(
                      title: GestureDetector(
                        child: Text(item["name"]),
                        onTap: () => someFunction()),
                    );
                  });
            } else {
              // 查询仍在运行
              return CircularProgressIndicator();
            }
          }),
    );
  }
}

class PageSelectBloc extends StatefulWidget {
  @override
  _PageSelectBlocState createState() => _PageSelectBlocState();
}

数据库模型

定义模型

从 4.0.0 版本开始,可以定义具有数据库方法的模型。主要优点是可以使用类型化的模型数据并避免每次查询时进行类型转换。直接将自定义模型插入到数据库中。例如:

schema.dart 中:

final carTable = DbTable("car")
  ..varchar("name")
  ..integer("max_speed")
  ..real("price")
  ..integer("year")
  ..boolean("is_4wd", defaultValue: false)
  ..foreignKey("manufacturer", onDelete: OnDelete.cascade);

final manufacturerTable = DbTable("manufacturer")..varchar("name");

car_model.dart 中:

import 'package:sqlcool/sqlcool.dart';
// 数据库模式
import 'schema.dart';
// 另一个模型
import 'manufacturer_model.dart';

class Car with DbModel {
  Car(
      {this.id,
      this.name,
      this.maxSpeed,
      this.price,
      this.year,
      this.is4wd,
      this.manufacturer});

  /// 定义一些类属性

  final String name;
  final int maxSpeed;
  final double price;
  final DateTime year;
  final bool is4wd;
  // 这是一个指向另一个模型的外键
  Manufacturer manufacturer;

  /// [DbModel] 必需的覆盖

  @override
  int id;

  /// [Db] 使用
  /// 将您的主数据库传递给它
  @override
  Db get db => db;

  /// 表模式表示
  /// 查看示例/pages/dbmodels/schema.dart
  @override
  DbTable get table => carTable;

  /// 序列化行以插入数据库
  @override
  Map<String, dynamic> toDb() {
    // 我们希望记录外键
    assert(manufacturer?.id != null);
    final row = {
      "name": name,
      "max_speed": maxSpeed,
      "price": price,
      "year": year.millisecondsSinceEpoch,
      "is_4wd": is4wd,
      "manufacturer": manufacturer.id
    };
    return row;
  }

  /// 从数据库反序列化一行
  @override
  Car fromDb(Map<String, dynamic> map) {
    final car = Car(
      id: map["id"] as int,
      name: map["name"].toString(),
      maxSpeed: map["max_speed"] as int,
      price: map["price"] as double,
      year: DateTime.fromMillisecondsSinceEpoch(map["year"] as int),
      is4wd: (map["is_4wd"].toString() == "true"),
    );
    // 仅在联合查询时存在此数据
    // 在简单的选择查询中不包含此数据
    if (map.containsKey("manufacturer")) {
      car.manufacturer =
          Manufacturer().fromDb(map["manufacturer"] as Map<String, dynamic>);
    }
    return car;
  }

  /// 为方便起见创建静态联合方法

  static Future<List<Car>> selectRelated({String where, int limit}) async {
    final cars = List<Car>.from(
        await Car().sqlJoin(where: where, limit: limit, verbose: true));
    return cars;
  }
}

然后使用这些模型:

/// car 是一个 [Car] 的实例
await car.sqlInsert();
await car.sqlUpdate();
await car.sqlUpsert();
await car.sqlDelete();
final cars = Car.selectRelated(where: "speed>200");
// 外键作为模型实例检索
print(cars[0].manufacturer.name);

更多关于Flutter数据库管理插件sqlcool2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据库管理插件sqlcool2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


sqlcool2 是 Flutter 中一个基于 sqflite 的数据库管理插件,它提供了一种更简洁、更高效的方式来管理 SQLite 数据库。sqlcool2 旨在简化数据库操作,提供类型安全、自动化的数据库迁移、以及更便捷的查询方式。

1. 安装 sqlcool2

首先,你需要在 pubspec.yaml 文件中添加 sqlcool2 依赖:

dependencies:
  flutter:
    sdk: flutter
  sqlcool2: ^1.0.0

然后运行 flutter pub get 来安装依赖。

2. 创建数据库

要使用 sqlcool2,首先需要创建一个数据库实例。你可以通过继承 Database 类来定义自己的数据库。

import 'package:sqlcool2/sqlcool2.dart';

class MyDatabase extends Database {
  MyDatabase() : super("my_database.db", version: 1);

  @override
  Future<void> onCreate(Database db, int version) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER NOT NULL
      )
    ''');
  }

  @override
  Future<void> onUpgrade(Database db, int oldVersion, int newVersion) async {
    // 处理数据库升级逻辑
  }
}

3. 初始化数据库

在使用数据库之前,你需要初始化它:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final db = MyDatabase();
  await db.init();
  runApp(MyApp(db: db));
}

4. 插入数据

你可以使用 insert 方法来插入数据:

Future<void> insertUser(String name, int age) async {
  final db = MyDatabase();
  await db.insert('users', {'name': name, 'age': age});
}

5. 查询数据

你可以使用 query 方法来查询数据:

Future<List<Map<String, dynamic>>> getUsers() async {
  final db = MyDatabase();
  return await db.query('users');
}

6. 更新数据

你可以使用 update 方法来更新数据:

Future<void> updateUser(int id, String name, int age) async {
  final db = MyDatabase();
  await db.update('users', {'name': name, 'age': age}, where: 'id = ?', whereArgs: [id]);
}

7. 删除数据

你可以使用 delete 方法来删除数据:

Future<void> deleteUser(int id) async {
  final db = MyDatabase();
  await db.delete('users', where: 'id = ?', whereArgs: [id]);
}

8. 使用事务

sqlcool2 支持事务操作:

Future<void> performTransaction() async {
  final db = MyDatabase();
  await db.transaction((txn) async {
    await txn.insert('users', {'name': 'Alice', 'age': 25});
    await txn.insert('users', {'name': 'Bob', 'age': 30});
  });
}

9. 数据库迁移

如果你需要升级数据库结构,可以在 onUpgrade 方法中处理:

@override
Future<void> onUpgrade(Database db, int oldVersion, int newVersion) async {
  if (oldVersion < 2) {
    await db.execute('ALTER TABLE users ADD COLUMN email TEXT');
  }
}

10. 关闭数据库

在应用程序退出时,可以关闭数据库连接:

Future<void> closeDatabase() async {
  final db = MyDatabase();
  await db.close();
}
回到顶部