搜索插件、代码仓与 APP 分类

插件详情v1.0.0

cozy_data

一种受 Swift 启发的 Flutter 持久化数据管理解决方案。提供简单、强大且类型安全的方式来持久化应用模型,并支持自动 UI 更新。

AndroidiOSmacOS
近 30 天下载
50
喜欢数
16
Pub 分数
130

安装插件

flutter pub add cozy_data

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

Cozy Data 是一个受 Swift 数据管理方法启发的 Flutter 包,提供了一种类型安全且直观的方式来使用 SQL 持久化应用模型。它会自动处理数据库操作,并在数据更改时触发 UI 更新,减少样板代码并提高开发速度。设计简洁可靠,可与 Flutter 的响应式框架无缝集成,非常适合需要实时 UI 同步的持久化存储应用。

适合场景

  • 离线优先的移动应用
  • 实时数据同步
  • 类型安全的模型持久化
  • 动态表单和列表状态管理
  • 应用设置和用户偏好存储

主要特点

  • 数据更改时自动更新 UI
  • 类型安全的数据建模
  • 受 Swift 启发的语法和设计
  • 内置的 CRUD 操作
  • 与 Flutter 小部件的无缝集成

适合对象

  • 寻求简单持久化的Flutter开发者
  • 需要离线功能的应用程序
  • 重视代码安全性和可维护性的团队
  • 频繁更改数据模型的项目
  • 熟悉 Swift 或类似声明式模式的开发者

使用建议

  • 仅限基于SQL的存储
  • 需要了解基本的数据库概念
  • 可能会为非常简单的用例引入开销
  • 不适合非结构化或大规模 NoSQL 需求

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

Cozy Data

Quickstart • Documentation • Sample Apps • Pub.dev

CozyData:
  1. SwiftData for flutter.
  2. Support sqflite, sqlite3, inMemory data Storage

A Swift-inspired persistent data management solution for Flutter. CozyData provides a simple, powerful, and type-safe way to persist your app's models and automatically update your UI when data changes.

Features

  • 🔄 Automatic UI updates when data changes
  • 🏃‍♂️ Fast and efficient database operations
  • 📱 Built specifically for Flutter
  • 💾 Simple persistent storage
  • 🔍 Powerful querying capabilities
  • 🎯 Type-safe data operations
  • 🧩 Easy-to-use annotations
  • 📦 Zero configuration needed

Quickstart

Add cozy_data to your pubspec.yaml:

1. Add to pubspec.yaml
dependencies:
  cozy_data: latest
  dart_mappable: latest

dev_dependencies:
  build_runner: any
  dart_mappable_builder: any

Usage

1. Define Your Models
import 'package:dart_mappable/dart_mappable.dart';
part 'recipe.mapper.dart';

@MappableClass()
class Recipe with RecipeMappable {
  final String persistentModelID; // This field is required for the cozy_data package to work
  String name;
  List<Ingredients>? ingredients;

  Recipe({required this.id, required this.name, this.ingredients});
}

@MappableClass()
class Ingredients with IngredientsMappable {
  String name;
  int? quantity;
  CookStyle cookStyle;
  Ingredients({required this.name, this.quantity, required this.cookStyle});
}

@MappableEnum()
enum CookStyle { bake, fry, boil }

and make sure to run dart run build_runner build after creating your model.

For more about the annotation please check dart_mappable.

2. Initialize CozyData

Initialize CozyData in your main.dart:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await CozyData.initialize(
      engine: CozyEngine.sqlite3,
      mappers: [RecipeMapper.ensureInitialized()]);

  runApp(MyApp());
}
 

the RecipeMapper will be generate in .mapper.dart file

Basic Operations

Save Data
final newRecipe = Recipe(
  persistentModelID: CozyId.cozyPersistentModelIDString(),
  name: 'salad',
  ingredients: [
    Ingredients(name: 'Tomato',quantity: 2,cookStyle: CookStyle.fry),
    Ingredients(name: 'Onion',quantity: 1,cookStyle: CookStyle.fry),
    Ingredients(name: 'Salt',quantity: 1,cookStyle: CookStyle.boil),
  ]
);

await CozyData.save<Recipe>(newRecipe);

Note: DataModel must be Specify <Recipe>

Delete Data

await CozyData.delete<Recipe>(model);

Update Data

await CozyData.update<Recipe>(updateRecipe);

Simple Query Data with UI Updates
class RecipeListView extends StatefulWidget {
  @override
  _RecipeListViewState createState() => _RecipeListViewState();
}

class _RecipeistViewState extends State<RecipeListView> {

final CozyQueryListener<Recipe> _recipeQuery = CozyData.queryListener<Recipe>();

  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
      listenable: _recipeQuery,
      builder: (context, _) {
        final recipes = _recipeQuery.items;
        return ListView.builder(
          itemCount: recipes.length,
          itemBuilder: (context, index) => ListTile(
            title: Text(recipes[index].name),
          ),
        );
      },
    );
  }

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

Fetch Data Once

final recipes = await CozyData.fetch<Recipe>();

Find by ID
final recipe = await CozyData.fetcById<Recipe>(persistentModelID: id);

Advanced Usage

The CozyQueryBuilder is a class used to construct complex SQL-like queries in a structured and programmatic way. It allows you to specify various components of a query, such as fields to group by, order by, having clauses, joins, limits, offsets, selected fields, subqueries, table aliases, and where conditions.


final customBuilder = CozyQueryBuilder(
// groupByFields: A list of fields by which the results should be grouped. In this case, it's an empty list, meaning no grouping is applied.
groupByFields: [],
// orderByFields: A list of fields by which the results should be ordered. It's also an empty list here, so no specific ordering is applied.
orderByFields: [],
// Conditions that filter the groups created by the groupBy clause. It's empty, indicating no such conditions.
havingClauses: [],
// joins: A list of join operations to combine rows from two or more tables based on a related column. No joins are specified here
joins: [],
// limit: The maximum number of records to return. Here, it's set to 10.
limit: 10,
// offset: The number of records to skip before starting to return records. It's set to 0, meaning no records are skipped.
offset: 0,
// selectFields: A list of fields to be selected in the query. It's empty, meaning all fields are selected
selectFields: [],
// subqueries: A list of subqueries to be included in the main query. It's empty, indicating no subqueries.
subqueries: [],
// tableAliases: A map of table aliases to be used in the query. It's an empty map here.
tableAliases: {},
// whereGroups: A list of conditions to filter the results. It's empty, meaning no filtering conditions are applied.
whereGroups: [],
);

Sorting and Filtering once

final recipes = await CozyData.fetch<Recipe>(customBuilder: customBuilder);

The CozyQueryController manages query operations for a CozyQueryListener. It allows adding where conditions, joins, order by fields, and custom queries to the listener.

Example usage:

  final controller = CozyQueryController<MyModel>();
  await controller.addWhere([PredicateGroup(predicates: [Predicate.equals('field', 'value')])]);
  await controller.addJoin([Join(table: 'other_table', condition: 'other_table.id = my_table.other_id')]);
  await controller.orderBy([OrderBy(field: 'created_at', direction: OrderDirection.desc)]);
  await controller.addCustomQuery(CozyQueryBuilder<MyModel>());
  await controller.reset();
Sorting and Filtering
// Controller
final CozyQueryController<Recipe> _queryController = CozyQueryController<Recipe>();

final CozyQueryListener<Recipe> _recipeQuery =
      CozyData.queryListener<Recipe>(controller: _queryController);

  await controller.addWhere([PredicateGroup(predicates: [Predicate.contains('field', 'value')])]);


Best Practices

  • Initialize Early: Call CozyData.initialize() as early as possible in your app lifecycle.

  • Dispose Queries: Always dispose of queries when they're no longer needed to prevent memory leaks.

Full Documentation

See the full documentation here or jump directly to the topic you are looking for:

所属分类

依赖

依赖清单 8 项

源码仓库

使用此插件的项目

暂无相关数据。