Flutter数据库交互插件brick_supabase的使用
Flutter数据库交互插件 brick_supabase
的使用
brick_supabase
是一个用于在 Flutter 应用中与 Supabase 数据库进行交互的插件。它基于 Brick 框架,提供了便捷的模型定义和查询功能。本文将详细介绍如何使用 brick_supabase
进行数据库操作,并提供完整的示例代码。
支持的查询配置
where:
Brick 目前不支持 Supabase 的所有过滤方法。在构建 Brick 查询时,请参考以下对比表:
Brick | Supabase |
---|---|
Compare.exact |
.eq |
Compare.notEqual |
.neq |
Compare.contains |
.like |
Compare.doesNotContain |
.not.like |
Compare.greaterThan |
.gt |
Compare.greaterThanOrEqualTo |
.gte |
Compare.lessThen |
.lt |
Compare.lessThenOrEqualTo |
.lte |
Compare.between |
.adj |
模型定义
@SupabaseSerializable(tableName:)
指定 Supabase 表名以连接 from
、upsert
和 delete
调用:
@SupabaseSerializable(tableName: 'users')
class User {
final String name;
User({required this.name});
}
@SupabaseSerializable(fieldRename:)
默认情况下,Brick 假设 Dart 字段名是 Supabase 列名的驼峰版本(例如 final String lastName => 'last_name'
)。可以通过设置 fieldRename
来重命名所有字段:
@SupabaseSerializable(fieldRename: FieldRename.pascal)
class User {
final String lastName;
}
fieldRename
只是默认转换方式,可以使用 @Supabase(name:)
对单个字段进行覆盖。
@SupabaseSerializable(defaultToNull:)
在 upsert
操作期间转发到 Supabase 的 defaultToNull
。
@SupabaseSerializable(ignoreDuplicates:)
在 upsert
操作期间转发到 Supabase 的 ignoreDuplicates
。
@SupabaseSerializable(onConflict:)
在 upsert
操作期间转发到 Supabase 的 onConflict
。
字段注解
@Supabase(unique:)
连接 Supabase 的主键或任何其他索引到应用程序代码,这对 upsert
和 delete
操作非常有用:
@Supabase(unique: true, name: 'uuid')
final String supabaseUuid;
@Supabase(enumAsString:)
如果 API 返回的是字符串而不是整数,则可以使用此注解:
enum Hat { baseball, bowler, birthday }
@Supabase(enumAsString: true)
final List<Hat> hats;
@Supabase(name:)
重命名 Supabase 键名:
@Supabase(name: "full_name")
final String lastName;
@Supabase(foreignKey:)
当字段类型扩展模型类型时,Supabase 列应为外键:
class User extends OfflineFirstWithSupabaseModel {
@Supabase(foreignKey: 'address_id')
final Address address;
}
class Address extends OfflineFirstWithSupabaseModel {
final String id;
}
@Supabase(ignoreFrom:)
和 @Supabase(ignoreTo:)
当为 true
时,字段将被忽略,不会参与序列化或反序列化。
测试
Mocking a Supabase Instance
在测试组中快速创建一个方便的模拟服务器:
import 'package:brick_supabase/testing.dart';
import 'package:test/test.dart';
void main() {
final mock = SupabaseMockServer(modelDictionary: supabaseModelDictionary);
group('MyClass', () {
setUp(mock.setUp);
tearDown(mock.tearDown);
test('#myMethod', () async {
final req = SupabaseRequest<MyModel>();
final resp = SupabaseResponse([
await mock.serialize(MyModel(name: 'Demo 1', id: '1')),
await mock.serialize(MyModel(name: 'Demo 2', id: '2')),
]);
mock.handle({req: resp});
final provider = SupabaseProvider(mock.client, modelDictionary: supabaseModelDictionary);
final retrieved = await provider.get<MyModel>();
expect(retrieved, hasLength(2));
});
});
}
示例代码
以下是一个完整的示例代码,展示了如何使用 brick_supabase
进行基本的 CRUD 操作:
import 'package:brick_core/core.dart';
import 'package:brick_supabase/brick_supabase.dart';
import 'package:supabase/supabase.dart';
/// 生成的适配器类
class UserAdapter extends SupabaseAdapter<User> {
@override
Future<User> fromSupabase(data, {required provider, repository}) async {
return User(
name: data['name'],
);
}
@override
Future<Map<String, dynamic>> toSupabase(instance, {required provider, repository}) async {
return {
'name': instance.name,
};
}
@override
final defaultToNull = false;
@override
final fieldsToSupabaseColumns = {'name': RuntimeSupabaseColumnDefinition(columnName: 'name')};
@override
final ignoreDuplicates = false;
@override
final onConflict = null;
@override
final tableName = 'users';
@override
final uniqueFields = {};
}
/// 生成的字典
final dictionary = SupabaseModelDictionary({
User: UserAdapter(),
});
/// 定义模型
class User extends SupabaseModel {
final String name;
User({required this.name});
}
/// 定义仓库
class MyRepository extends SingleProviderRepository<SupabaseModel> {
MyRepository(String apiUrl, String supabaseAnonKey)
: super(
SupabaseProvider(
SupabaseClient(apiUrl, supabaseAnonKey),
modelDictionary: dictionary,
),
);
}
void main() async {
final repository = MyRepository('http://localhost:8080', 'YOUR_API_KEY_HERE');
// 获取用户列表
final users = await repository.get<User>();
print(users);
// 创建新用户
final newUser = User(name: 'John Doe');
await repository.upsert(newUser);
// 更新用户信息
final updatedUser = User(name: 'Jane Doe');
await repository.upsert(updatedUser);
// 删除用户
await repository.delete<User>(id: 'user_id');
}
以上代码展示了如何定义模型、适配器、字典以及如何使用仓库进行数据操作。希望这些内容能帮助你更好地理解和使用 brick_supabase
插件。
更多关于Flutter数据库交互插件brick_supabase的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据库交互插件brick_supabase的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用Flutter数据库交互插件brick_supabase
的示例代码案例。这个插件允许你轻松地在Flutter应用中使用Supabase作为后端数据库。
首先,你需要确保已经在你的pubspec.yaml
文件中添加了brick_supabase
依赖:
dependencies:
flutter:
sdk: flutter
brick_supabase: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
接下来,你需要设置Supabase的客户端。这通常包括你的Supabase URL和匿名密钥。你可以在Supabase的仪表板上找到这些信息。
以下是一个完整的示例,展示如何使用brick_supabase
插件进行基本的数据库操作,如插入、查询和更新数据:
import 'package:flutter/material.dart';
import 'package:brick_supabase/brick_supabase.dart';
void main() {
// 配置Supabase客户端
final supabaseClient = SupabaseClient(
supabaseUrl: 'https://你的项目名.supabase.co', // 替换为你的Supabase URL
supabaseAnonKey: '你的匿名密钥', // 替换为你的Supabase匿名密钥
);
runApp(MyApp(supabaseClient: supabaseClient));
}
class MyApp extends StatelessWidget {
final SupabaseClient supabaseClient;
MyApp({required this.supabaseClient});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Supabase Flutter Demo'),
),
body: Center(
child: SupabaseDemo(supabaseClient: supabaseClient),
),
),
);
}
}
class SupabaseDemo extends StatefulWidget {
final SupabaseClient supabaseClient;
SupabaseDemo({required this.supabaseClient});
@override
_SupabaseDemoState createState() => _SupabaseDemoState();
}
class _SupabaseDemoState extends State<SupabaseDemo> {
late String resultText = '';
@override
void initState() {
super.initState();
_insertData();
_fetchData();
// _updateData(); // 你可以取消注释来测试更新数据
// _deleteData(); // 你可以取消注释来测试删除数据
}
Future<void> _insertData() async {
try {
final response = await widget.supabaseClient.from('your_table_name').insert({
'name': 'John Doe',
'email': 'john.doe@example.com',
});
print('Insert Response: ${response.data}');
} catch (e) {
print('Error inserting data: $e');
}
}
Future<void> _fetchData() async {
try {
final response = await widget.supabaseClient.from('your_table_name').select();
final data = response.data!;
if (data.isNotEmpty) {
setState(() {
resultText = data.first['name']!; // 显示第一个条目的名字
});
} else {
setState(() {
resultText = 'No data found';
});
}
} catch (e) {
print('Error fetching data: $e');
}
}
// 示例更新函数(你可以根据需要修改)
Future<void> _updateData() async {
try {
final response = await widget.supabaseClient.from('your_table_name')
.update({'email': 'john.newemail@example.com'})
.eq({'id': '需要更新的记录的ID'}); // 替换为实际的ID
print('Update Response: ${response.data}');
} catch (e) {
print('Error updating data: $e');
}
}
// 示例删除函数(你可以根据需要修改)
Future<void> _deleteData() async {
try {
final response = await widget.supabaseClient.from('your_table_name')
.delete()
.eq({'id': '需要删除的记录的ID'}); // 替换为实际的ID
print('Delete Response: ${response.data}');
} catch (e) {
print('Error deleting data: $e');
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Result: $resultText'),
ElevatedButton(
onPressed: () async {
setState(() {
resultText = 'Refreshing...';
});
await _fetchData();
},
child: Text('Refresh Data'),
),
],
);
}
}
在这个示例中,我们创建了一个Flutter应用,该应用使用brick_supabase
插件与Supabase数据库进行交互。我们演示了如何插入、查询数据,并提供了更新和删除数据的示例函数(这些函数在initState
中被注释掉了,但你可以根据需要取消注释以测试它们)。
请注意,你需要将your_table_name
替换为你实际的Supabase表名,并根据需要调整其他字段和值。此外,更新和删除操作需要指定要更新或删除的记录的ID,你需要根据实际情况进行替换。