Flutter类型安全Supabase操作插件typesafe_supabase的使用

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

Flutter类型安全Supabase操作插件typesafe_supabase的使用

类型安全Supabase插件介绍

🚨 这不是官方的supabase包,并且不是由supabase团队开发的!

  • ✅ ⚡️ 类型安全查询
  • ✅ ⚡️ 防错过滤器
  • ✅ ⚡️ 防错修改器
  • ✅ ⚡️ 极简设置
  • ✅ ⚡️ 极小代码生成

基本用法

🚧 WIP! 此包仍在开发中。谨慎使用,并在此链接上报告任何潜在问题。

创建表结构

首先,创建与Supabase项目中的表相匹配的表结构:

// authors.dart

import 'package:typesafe_supabase/typesafe_supabase.dart';

part 'authors.g.dart';

/// 代表Supabase数据库中的`authors`表。
@SupaTableHere()
class Authors extends SupaTable<AuthorsCore, AuthorsRecord> {
  const Authors({required super.supabaseClient})
      : super(AuthorsRecord.new, tableName: 'authors', primaryKey: const ['id']);

  /// 作者的唯一标识符。
  @SupaColumnHere<BigInt>(hasDefault: true)
  static const id = SupaColumn<AuthorsCore, BigInt, int>(name: 'id');

  /// 作者的名字。
  @SupaColumnHere<String>()
  static const name = SupaColumn<AuthorsCore, String, String>(name: 'name');
}
// books.dart

import 'package:typesafe_supabase/typesafe_supabase.dart';

part 'books.g.dart';

/// 代表Supabase数据库中的`books`表。
@SupaTableHere()
class Books extends SupaTable<BooksCore, BooksRecord> {
  const Books({required super.supabaseClient})
      : super(BooksRecord.new, tableName: 'books', primaryKey: const ['id']);

  /// 书籍的唯一标识符。
  @SupaColumnHere<BigInt>(hasDefault: true)
  static const id = SupaColumn<BooksCore, BigInt, int>(name: 'id');

  /// 书籍的标题。
  @SupaColumnHere<String>()
  static const title = SupaColumn<BooksCore, String, String>(name: 'title');

  /// 书籍作者的唯一标识符。
  @SupaColumnHere<BigInt>()
  static const authorID = SupaColumn<BooksCore, BigInt, int>(name: 'author_id');

  /// 书籍的页数。
  @SupaColumnHere<int?>()
  static const pages = SupaColumn<BooksCore, int?, int?>(name: 'pages');

  /// 引用通过`author_id`列连接的`authors`表。
  @SupaTableJoinHere('Authors', 'authors', SupaJoinType.oneToOne, isNullable: false)
  static final author = SupaTableJoin<BooksCore, AuthorsCore>(
    tableName: 'authors',
    joiningColumn: Books.authorID,
    joinType: SupaJoinType.oneToOne,
    record: AuthorsRecord.new,
  );
}

运行代码生成器

接下来,运行生成器以生成一小段代码:

dart run build_runner build

使用插件

现在可以开始使用了!

import 'dart:io';

import 'package:supabase/supabase.dart';
import 'package:typesafe_supabase/typesafe_supabase.dart';
import 'package:typesafe_supabase_example/secrets.dart';
import 'package:typesafe_supabase_example/tables/authors.dart';
import 'package:typesafe_supabase_example/tables/books.dart';

void main() async {
  final supabaseClient = SupabaseClient(
    SUPABASE_PROJECT_URL,
    SUPABASE_ANON_KEY,
  );

  // 创建books表。
  final books = Books(supabaseClient: supabaseClient);

  // 获取一本名为Paddington的书。
  final book = await books.fetch(
    columns: {
      Books.title,
      Books.author({Authors.name}),
    },
    filter: books.textSearch(Books.title('Paddington')),
    modifier: books.order(Books.title).limit(1).single(),
  );

  // 打印书名。
  print(book.title);
  // 打印作者名字。
  print(book.author.name);

  // 插入一本新的Paddington书。
  await books.insert(
    records: [
      BooksInsert(title: 'To be updated', authorID: BigInt.two, pages: 160),
    ],
    modifier: books.none(),
  );

  // 更新ID为4的书的标题和作者。
  await books.update(
    values: {
      Books.title('Paddington Here and Now'),
      Books.authorID(BigInt.one),
    },
    filter: books.equal(Books.id(BigInt.from(4))),
    modifier: books.none(),
  );

  // 删除所有不是Michael Bond写的Paddington书。
  await books.delete(
    filter: books
        .textSearch(Books.title('Paddington'))
        .notEqual(Books.authorID(BigInt.one)),
    modifier: books.none(),
  );

  exit(0);
}

更多关于Flutter类型安全Supabase操作插件typesafe_supabase的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter类型安全Supabase操作插件typesafe_supabase的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,我可以为你提供一个关于如何在Flutter中使用typesafe_supabase插件进行类型安全Supabase操作的示例代码。typesafe_supabase是一个帮助你在Flutter应用中与Supabase进行类型安全交互的插件。

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

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

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

接下来是一个完整的示例代码,展示如何使用typesafe_supabase进行基本的数据库操作,比如插入、查询和更新数据。

1. 配置Supabase

首先,配置你的Supabase客户端。确保你已经从Supabase控制台获取了URL和匿名密钥。

import 'package:flutter/material.dart';
import 'package:supabase_dart/supabase_dart.dart';
import 'package:typesafe_supabase/typesafe_supabase.dart';

part 'models/user.dart';  // 假设你有一个User模型

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

class MyApp extends StatelessWidget {
  final SupabaseClient supabase = SupabaseClient(
    url: 'YOUR_SUPABASE_URL',
    anonKey: 'YOUR_ANON_KEY'
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Supabase Example'),
        ),
        body: Center(
          child: SupabaseExample(supabase: supabase),
        ),
      ),
    );
  }
}

2. 定义数据模型

models/user.dart文件中定义你的数据模型。使用@SupabaseTable@SupabaseColumn注解来标记表和列。

// models/user.dart
import 'package:typesafe_supabase/typesafe_supabase.dart';

@SupabaseTable('users')
class User {
  @SupabaseColumn('id')
  final String? id;

  @SupabaseColumn('name')
  final String name;

  @SupabaseColumn('email')
  final String email;

  User({required this.name, required this.email, this.id});

  factory User.fromJson(Map<String, dynamic> json) => User(
    id: json['id'] as String?,
    name: json['name'] as String,
    email: json['email'] as String,
  );

  Map<String, dynamic> toJson() => {
    'id': id,
    'name': name,
    'email': email,
  };
}

3. 使用typesafe_supabase进行数据库操作

在你的Flutter组件中,使用typesafe_supabase进行数据库操作。

import 'package:flutter/material.dart';
import 'package:supabase_dart/supabase_dart.dart';
import 'package:typesafe_supabase/typesafe_supabase.dart';
import 'models/user.dart';

class SupabaseExample extends StatefulWidget {
  final SupabaseClient supabase;

  SupabaseExample({required this.supabase});

  @override
  _SupabaseExampleState createState() => _SupabaseExampleState();
}

class _SupabaseExampleState extends State<SupabaseExample> {
  late final SupabaseRepository<User> userRepository;

  @override
  void initState() {
    super.initState();
    userRepository = SupabaseRepository<User>(
      supabase: widget.supabase,
      fromJson: User.fromJson,
      toJson: (user) => user.toJson(),
    );
  }

  void _insertUser() async {
    final user = User(name: 'John Doe', email: 'john.doe@example.com');
    await userRepository.insert(user);
  }

  void _queryUsers() async {
    final users = await userRepository.selectAll();
    print(users);
  }

  void _updateUser() async {
    final user = await userRepository.selectById('your-user-id');
    if (user != null) {
      final updatedUser = user.copyWith(email: 'john.newemail@example.com');
      await userRepository.update(updatedUser);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: _insertUser,
          child: Text('Insert User'),
        ),
        ElevatedButton(
          onPressed: _queryUsers,
          child: Text('Query Users'),
        ),
        ElevatedButton(
          onPressed: _updateUser,
          child: Text('Update User'),
        ),
      ],
    );
  }
}

注意

  1. 错误处理:在实际应用中,你应该添加错误处理逻辑,比如处理网络错误和数据库错误。
  2. 安全性:确保不要将敏感信息硬编码到你的代码中,特别是密钥和URL。使用环境变量或安全存储来管理这些信息。
  3. 依赖管理:确保你使用的是最新版本的typesafe_supabasesupabase_dart

以上代码展示了如何使用typesafe_supabase插件在Flutter中进行类型安全的Supabase数据库操作。希望这对你有所帮助!

回到顶部