Flutter查询构建器插件flutter_query_builder的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter查询构建器插件flutter_query_builder的使用

flutter_query_builder 简化了数据库交互,使得创建、检索、更新和删除记录变得简单。告别繁琐的手动SQL查询,拥抱flutter_query_builder带来的简洁与强大。

开始使用

添加依赖

pubspec.yaml文件中添加依赖:

dependencies:
  flutter_query_builder: ^1.0.0

初始化数据库

导入sqflite并开始初始化你的数据库:

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

class DataBaseManagment {
  static late Database database;

  static Future<Database> initDatabase({
    required String dbName,
    int? version,
    FutureOr<void> Function(Database)? onOpen,
    FutureOr<void> Function(Database, int)? onCreate,
    FutureOr<void> Function(Database)? onConfigure,
    FutureOr<void> Function(Database, int, int)? onDowngrade,
    FutureOr<void> Function(Database, int, int)? onUpgrade,
    bool? readOnly = false,
    bool? singleInstance = true,
  }) async {
    var databasesPath = await getDatabasesPath();
    String path = '$databasesPath/$dbName';
    // 打开数据库
    try {
      database = await openDatabase(
        path,
        version: version,
        onOpen: onOpen,
        onConfigure: onConfigure,
        onDowngrade: onDowngrade,
        onUpgrade: onUpgrade,
        singleInstance: singleInstance,
        readOnly: readOnly,
        onCreate: onCreate,
      );
      print('$dbName 数据库初始化成功,路径为 $path');
    } catch (e) {
      print('初始化 $dbName 数据库时出错: $e');
    }
    return database;
  }
}

void main() async {
  await DataBaseManagment.initDatabase(dbName: 'test', version: 1);
  runApp(const MyApp());
}

基础数据

我们假设已经有了以下基础数据来解释主要功能:

TableModel student = TableModel(
  name: 'Student',
  columns: [
    ColumnModel(
      name: 'studentId',
      isAutoincrement: true,
      isPrimaryKey: true,
      isNotNull: true,
      isInteger: true,
    ),
    ColumnModel(name: 'name', isText: true),
    ColumnModel(name: 'collageId', isInteger: true),
  ],
);

TableModel collage = TableModel(
  name: 'Collage',
  columns: [
    ColumnModel(
      name: 'collageId',
      isAutoincrement: true,
      isPrimaryKey: true,
      isNotNull: true,
      isInteger: true,
    ),
    ColumnModel(name: 'name', isVarchar: true, varcharCharCount: 50),
    ColumnModel(name: 'address', isText: true),
  ],
);

超级简单的使用方法

创建表

await QueryBuilder.createTable(
  table: collage,
  whenError: (error) {
    log('Error 👾: $error');
  },
);

获取表内容

await QueryBuilder.getTableContent(
  tableName: collage.name,
  whenError: (error) {
    log('Error 👾: $error');
  },
);

重命名表

await QueryBuilder.renameTable(
  table: student,
  newName: 'first Table',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

获取表名

await QueryBuilder.getTablesNames(
  whenError: (error) {
    log('Error 👾: $error');
  },
);

删除表

await QueryBuilder.dropTable(
  table: student,
  whenError: (error) {
    log('Error 👾: $error');
  },
);

添加新列

await QueryBuilder.addNewColumn(
  table: student,
  column: ColumnModel(
    name: 'bio',
    isReal: true,
  ),
  whenError: (error) {
    log('Error 👾: $error');
  },
);

更新列值

await QueryBuilder.updateColumnValue(
  table: student,
  columnName: 'ID_adress',
  newColumnValue: 'NewName',
  condition: ConditionModel(
    key: 'id',
    condition: ConditionType.equalTo,
    val: 5,
  ),
  whenError: (error) {},
);

获取表中所有列名

await QueryBuilder.getColumnNames(student.name);

重命名列

await QueryBuilder.renameColumn(
  table: student,
  oldName: 'name',
  newName: 'newName',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

插入记录

await QueryBuilder.insertRecord(
  table: collage,
  record: RecordModel(
    data: [
      RecordItemModel(columnName: 'name', value: 'Emran Maher Al-daqaq'),
      RecordItemModel(columnName: 'address', value: 'Duff Fork Villas'),
      RecordItemModel(columnName: 'collageId', value: 5),
    ]),
  whenError: (error) {
    log('Error 👾: $error');
  },
);

更新记录

await QueryBuilder.updateRecord(
  table: student,
  newRecord: [
    RecordItemModel(columnName: 'name', value: 'new name'),
    RecordItemModel(columnName: 'age', value: '10'),
    RecordItemModel(columnName: 'ID_adress', value: 65),
    RecordItemModel(columnName: 'have', value: false),
    RecordItemModel(columnName: 'haveCat', value: 0),
  ],
  condition: ConditionModel(
    key: 'id',
    condition: ConditionType.notEqualTo,
    val: 6,
  ),
  whenError: (error) {
    log('Error 👾: $error');
  },
);

删除记录

await QueryBuilder.deleteRecord(
  table: student,
  condition: ConditionModel(
    key: 'haveTV',
    condition: ConditionType.equalTo,
    val: 0,
  ),
  whenError: (error) {
    log('Error 👾: $error');
  },
);

联合查询

await QueryBuilder.union(
  type: UnionType.union, // 或者使用 UnionType.unionAll
  firstRowSelect: 'SELECT bio FROM ${student.name}',
  secondRowSelect: 'SELECT bio FROM ${student.name}',
  orderByColumn: 'bio',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

联合所有查询

await QueryBuilder.union(
  type: UnionType.unionAll,
  firstRowSelect: 'SELECT bio FROM ${student.name}',
  secondRowSelect: 'SELECT bio FROM ${student.name}',
  orderByColumn: 'bio',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

内连接查询

await QueryBuilder.join(
  type: JoinType.inner,
  rowSelect:
    'SELECT ${collage.name}.address,${student.name}.name FROM ${student.name}',
  secondTableName: collage.name,
  firstColumnName: '${collage.name}.collageId',
  secondColumnName: '${student.name}.collageId',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

左连接查询

await QueryBuilder.join(
  type: JoinType.left,
  rowSelect:
    'SELECT ${collage.name}.address,${student.name}.name FROM ${student.name}',
  secondTableName: collage.name,
  firstColumnName: '${collage.name}.collageId',
  secondColumnName: '${student.name}.collageId',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

行查询

await QueryBuilder.rawQuery(
  'query',
  whenError: (error) {
    log('Error 👾: $error');
  },
);

删除数据库

await deleteDataBase(String dbName);

结论

是不是非常简单呢?

如果你觉得这个项目有用

如果你觉得这个项目有用,请考虑给它一个星星并在社交媒体上分享它。

联系信息

链接: LinkedIn

链接: Facebook


示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';
import 'package:flutter_query_builder/flutter_query_builder.dart';
import 'dart:developer';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'flutter_query_builder',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            children: [
              // ~ Initializing data base
              const Center(child: Text('Initializing data base')),
              ButtonsWidget(
                title: 'Initializing data base',
                onTap: () async {
                  await DataBaseManagment.initDatabase(
                      dbName: 'test1', version: 1);
                },
              ),

              // ~ Tables
              const Center(child: Text('Tables')),
              ButtonsWidget(
                title: 'Create Table',
                onTap: () async {
                  await QueryBuilder.createTable(
                    table: collage,
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Get Table Content',
                onTap: () async {
                  await QueryBuilder.getTableContent(
                    tableName: collage.name,
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Rename Table',
                onTap: () async {
                  await QueryBuilder.renameTable(
                    table: student,
                    newName: 'first Table',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Get Table Names',
                onTap: () async {
                  await QueryBuilder.getTablesNames(
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Drop Table',
                onTap: () async {
                  await QueryBuilder.dropTable(
                    table: student,
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),

              // ~ Columns
              const Center(child: Text('Columns')),

              ButtonsWidget(
                title: 'Add New Column',
                onTap: () async {
                  await QueryBuilder.addNewColumn(
                    table: student,
                    column: ColumnModel(
                      name: 'bio',
                      isReal: true,
                    ),
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),

              ButtonsWidget(
                title: 'Update Column Value',
                onTap: () async {
                  await QueryBuilder.updateColumnValue(
                    table: student,
                    columnName: 'ID_adress',
                    newColumnValue: 'hi',
                    condition: ConditionModel(
                      key: 'id',
                      condition: ConditionType.equalTo,
                      val: 5,
                    ),
                    whenError: (error) {},
                  );
                },
              ),

              ButtonsWidget(
                title: 'Column Names In Table',
                onTap: () async {
                  await QueryBuilder.getColumnNames(collage.name);
                },
              ),
              ButtonsWidget(
                title: 'Rename Column',
                onTap: () async {
                  await QueryBuilder.renameColumn(
                    table: student,
                    oldName: 'have4324',
                    newName: 'havek',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),

              // ~ Reords

              const Center(child: Text('Records')),

              ButtonsWidget(
                title: 'Insert Record',
                onTap: () async {
                  await QueryBuilder.insertRecord(
                    table: collage,
                    record: RecordModel(data: [
                      RecordItemModel(
                          columnName: 'name', value: 'Duff Fork Villas'),
                      RecordItemModel(columnName: 'address', value: 'test2'),
                      RecordItemModel(columnName: 'collageId', value: 5),
                    ]),
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Update Record',
                onTap: () async {
                  await QueryBuilder.updateRecord(
                    table: student,
                    newRecord: [
                      RecordItemModel(columnName: 'name', value: 'Erhamny'),
                      RecordItemModel(columnName: 'age', value: '10'),
                      RecordItemModel(columnName: 'ID_adress', value: 65),
                      RecordItemModel(columnName: 'have', value: false),
                      RecordItemModel(columnName: 'haveCat', value: 0),
                    ],
                    condition: ConditionModel(
                        key: 'id', condition: ConditionType.notEqualTo, val: 6),
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Delete Record',
                onTap: () async {
                  await QueryBuilder.deleteRecord(
                    table: student,
                    condition: ConditionModel(
                        key: 'haveTV',
                        condition: ConditionType.equalTo,
                        val: 0),
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),

              // ~ Union

              const Center(child: Text('Union')),

              ButtonsWidget(
                title: 'Union',
                onTap: () async {
                  await QueryBuilder.union(
                    type: UnionType.union,
                    firstRowSelect: 'SELECT bio FROM ${student.name}',
                    secondRowSelect: 'SELECT bio FROM ${student.name}',
                    orderByColumn: 'bio',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              ButtonsWidget(
                title: 'Union All',
                onTap: () async {
                  await QueryBuilder.union(
                    type: UnionType.unionAll,
                    firstRowSelect: 'SELECT bio FROM ${student.name}',
                    secondRowSelect: 'SELECT bio FROM ${student.name}',
                    orderByColumn: 'bio',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              // ~ Inner Join
              const Center(child: Text('Join')),
              ButtonsWidget(
                title: 'Inner Join',
                onTap: () async {
                  JoinType.inner;
                  JoinType.left;
                  await QueryBuilder.join(
                    type: JoinType.inner,
                    rowSelect:
                        'SELECT ${collage.name}.address,${student.name}.name FROM ${student.name}',
                    secondTableName: collage.name,
                    firstColumnName: '${collage.name}.collageId',
                    secondColumnName: '${student.name}.collageId',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              // ~ left Join
              ButtonsWidget(
                title: 'Left Join',
                onTap: () async {
                  await QueryBuilder.join(
                    type: JoinType.left,
                    rowSelect:
                        'SELECT ${collage.name}.address,${student.name}.name FROM ${student.name}',
                    secondTableName: collage.name,
                    firstColumnName: '${collage.name}.collageId',
                    secondColumnName: '${student.name}.collageId',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
              // ~ Row Query

              const Center(child: Text('Row Query')),

              ButtonsWidget(
                title: 'Row Query',
                onTap: () async {
                  await QueryBuilder.rawQuery(
                    'query',
                    whenError: (error) {
                      log('Error 👾: $error');
                    },
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class ButtonsWidget extends StatelessWidget {
  const ButtonsWidget({
    super.key,
    required this.onTap,
    required this.title,
  });
  final VoidCallback onTap;
  final String title;
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ElevatedButton(
        onPressed: onTap,
        child: Text(title),
      ),
    );
  }
}

// ~ dummy data

TableModel student = TableModel(
  name: 'Student',
  columns: [
    ColumnModel(
      name: 'studentId',
      isAutoincrement: true,
      isPrimaryKey: true,
      isNotNull: true,
      isInteger: true,
    ),
    ColumnModel(name: 'name', isText: true),
    ColumnModel(name: 'collageId', isInteger: true),
  ],
);

TableModel collage = TableModel(
  name: 'Collage',
  columns: [
    ColumnModel(
      name: 'collageId',
      isAutoincrement: true,
      isPrimaryKey: true,
      isNotNull: true,
      isInteger: true,
    ),
    ColumnModel(name: 'name', isVarchar: true, varcharCharCount: 50),
    ColumnModel(name: 'address', isText: true),
  ],
);

更多关于Flutter查询构建器插件flutter_query_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter查询构建器插件flutter_query_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用flutter_query_builder插件的示例代码案例。这个插件通常用于构建动态查询界面,允许用户根据条件筛选数据。

首先,确保你已经在pubspec.yaml文件中添加了flutter_query_builder依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_query_builder: ^最新版本号  # 请替换为最新版本号

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

接下来,我们可以开始构建一个简单的查询界面。假设我们有一个用户列表,用户可以根据名字或年龄进行筛选。

主应用代码(main.dart)

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Query Builder Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: QueryBuilderDemo(),
    );
  }
}

class QueryBuilderDemo extends StatefulWidget {
  @override
  _QueryBuilderDemoState createState() => _QueryBuilderDemoState();
}

class _QueryBuilderDemoState extends State<QueryBuilderDemo> {
  late QueryBuilder<User> queryBuilder;

  @override
  void initState() {
    super.initState();

    // 定义字段和规则
    final nameField = QueryBuilderField<User, String>(
      'name',
      label: 'Name',
      fieldBuilder: (User user) => user.name,
      ruleBuilders: [
        QueryBuilderRuleBuilder<String>(
          type: 'is_equal_to',
          label: 'Is equal to',
          inputBuilder: (context) => TextFormField(),
          valueSerializer: (value) => value,
          valueDeserializer: (value) => value,
          applyRule: (user, value) => user.name == value,
        ),
      ],
    );

    final ageField = QueryBuilderField<User, int>(
      'age',
      label: 'Age',
      fieldBuilder: (User user) => user.age,
      ruleBuilders: [
        QueryBuilderRuleBuilder<int>(
          type: 'is_greater_than',
          label: 'Is greater than',
          inputBuilder: (context) => TextFormField(
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              prefixText: '>',
            ),
          ),
          valueSerializer: (value) => value.toString(),
          valueDeserializer: (value) => int.parse(value),
          applyRule: (user, value) => user.age > value,
        ),
      ],
    );

    // 创建QueryBuilder实例
    queryBuilder = QueryBuilder<User>(
      fields: [nameField, ageField],
      rules: [],
      applyFilters: (users, rules) {
        return users.where((user) {
          for (final rule in rules) {
            if (!rule.apply(user)) {
              return false;
            }
          }
          return true;
        }).toList();
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Query Builder Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            QueryBuilderWidget<User>(
              queryBuilder: queryBuilder,
              onRulesChanged: (rules) {
                // 用户改变规则时触发
                setState(() {}); // 假设你有一个用户列表,这里可以刷新列表
              },
            ),
            SizedBox(height: 16),
            // 假设的用户列表(这里仅作为示例)
            Expanded(
              child: ListView.builder(
                itemCount: 10, // 假设有10个用户
                itemBuilder: (context, index) {
                  final user = User(name: 'User $index', age: index * 5);
                  // 应用过滤逻辑(这里简单返回所有用户,实际应用中根据queryBuilder.applyFilters处理)
                  return ListTile(
                    title: Text('${user.name} (${user.age} years old)'),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// 示例用户模型
class User {
  final String name;
  final int age;

  User({required this.name, required this.age});
}

解释

  1. 依赖添加:在pubspec.yaml文件中添加flutter_query_builder依赖。
  2. 定义字段和规则:在_QueryBuilderDemoState类中,我们定义了两个字段(nameage)以及它们对应的规则。每个字段都有一个或多个规则构建器(QueryBuilderRuleBuilder),用于定义如何应用这些规则。
  3. 创建QueryBuilder实例:我们使用定义的字段和规则创建了一个QueryBuilder<User>实例。
  4. 构建界面:使用QueryBuilderWidget来渲染查询构建器界面,并处理规则变化。在示例中,我们简单地显示了一个用户列表,实际应用中应该根据规则过滤用户列表。

这个示例展示了如何设置flutter_query_builder插件,并构建一个简单的查询界面。你可以根据需要扩展这个示例,添加更多字段和规则。

回到顶部