Flutter查询构建器插件flutter_query_builder的使用
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
更多关于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});
}
解释
- 依赖添加:在
pubspec.yaml
文件中添加flutter_query_builder
依赖。 - 定义字段和规则:在
_QueryBuilderDemoState
类中,我们定义了两个字段(name
和age
)以及它们对应的规则。每个字段都有一个或多个规则构建器(QueryBuilderRuleBuilder
),用于定义如何应用这些规则。 - 创建QueryBuilder实例:我们使用定义的字段和规则创建了一个
QueryBuilder<User>
实例。 - 构建界面:使用
QueryBuilderWidget
来渲染查询构建器界面,并处理规则变化。在示例中,我们简单地显示了一个用户列表,实际应用中应该根据规则过滤用户列表。
这个示例展示了如何设置flutter_query_builder
插件,并构建一个简单的查询界面。你可以根据需要扩展这个示例,添加更多字段和规则。