Flutter对象关系映射插件flutter_orm的使用

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

Flutter对象关系映射插件flutter_orm的使用

flutter_orm 是一个基于注解的ORM库,灵感来源于Android的Room持久化库。它基于 sqflite,提供了更友好的API,并支持Android、iOS和MacOS。

主要特性

  • 简单的API用于创建数据库和实体
  • 支持CRUD操作
  • 支持事务
  • 支持自定义类型转换器
  • 支持迁移
  • 支持嵌入字段
  • 支持外键

使用示例

1. 添加依赖

在你的Flutter项目中添加以下依赖:

dependencies:
  flutter_orm:
  sqflite:

dev_dependencies:
  flutter_orm_generator:
  build_runner:

2. 导入库

import 'package:flutter_orm/flutter_orm.dart';

注意:如果你对数据库结构(包括DB、Dao、Entity等)进行了任何更改,必须运行以下命令来应用更改:

flutter pub run build_runner build --delete-conflicting-outputs;

3. 定义实体(表)

使用 @Entity 注解来定义一个实体或表。你可以设置 tableNameindices 属性。如果没有指定 tableName,则默认使用类名作为表名。

@Entity(tableName: 'notes', indices: [
  Index(columns: ['text'], unique: true)
])
class Note {
  @PrimaryKey(autoGenerate: true)
  final int? id;

  final String text;
  final bool isEdited;
  final DateTime createDate;
  final DateTime? updateDate;

  @Column(name: 'lat')
  final double? latitude;

  @Column(name: 'lng')
  final double? longitude;

  @Ignore()
  final String? ignoreTest;

  @Column(name: 'defaultValueTest1', defaultValue: 'test')
  final String? defaultValueTest1;

  @Column(name: 'defaultValueTest2', defaultValue: '0')
  final int? defaultValueTest2;

  Note({
    this.id,
    required this.text,
    required this.isEdited,
    required this.createDate,
    this.updateDate,
    this.latitude,
    this.longitude,
    this.ignoreTest,
    this.defaultValueTest1,
    this.defaultValueTest2,
  });
}

4. 定义数据库

使用 @DB 注解定义数据库,并指定版本号和实体列表。

@DB(
  name: 'note_db',
  version: 1,
  entities: [Note],
)
abstract class NoteDB {
  @OnUpgrade()
  Future<void> onUpgrade(Database db, int oldVersion, int newVersion) async {
    print('onUpgrade');
  }

  @OnDowngrade()
  Future<void> onDowngrade(Database db, int oldVersion, int newVersion) async {
    print('onDowngrade');
  }

  @OnConfigure()
  Future<void> onConfigure(Database db) async {
    db.execute('PRAGMA foreign_keys = ON;');
  }

  @OnOpen()
  Future<void> onOpen(Database db) async {
    print('onOpen');
  }
}

5. 数据访问对象(DAO)

使用 @Dao 注解定义数据访问对象(DAO),并在其中定义方法来访问和操作数据。

@Dao()
abstract class NoteDao {
  @Insert(onConflict: OnConflictStrategy.ignore)
  Future<void> insert(Note note);

  @Query("select * from Note")
  Future<List<Note>> all();

  @Delete()
  Future<void> delete(Note note);
}

6. 数据库构建器

使用 @DBBuilder 注解定义一个抽象类,用于初始化数据库并生成访问数据库的方法。

@DBBuilder(databases: [NoteDB])
abstract class DatabaseBuilder {}

7. 初始化数据库

NoteDB noteDB = await DBContext.getNoteDB();
final dao = noteDB.noteDao();
int count = await dao.count() ?? 0;

8. 示例代码

以下是一个完整的示例,展示了如何使用 flutter_orm 插件来创建一个简单的笔记应用程序。

import 'package:flutter/material.dart';
import 'package:example/database_builder/database_builder.dart';
import 'package:example/db/note_db.dart';
import 'package:example/entities/note.dart';
import 'package:example/pages/notes_list_page.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ORM Demo',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const MyHomePage(title: 'ORM Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late NoteDB noteDB;
  bool _initialized = false;

  [@override](/user/override)
  void initState() {
    super.initState();
    _initDB();
  }

  void _initDB() {
    DBContext.getNoteDB().then((db) {
      noteDB = db;
      _insertMockNote().then((_) {
        Future.delayed(const Duration(seconds: 3)).then((value) {
          setState(() {
            _initialized = true;
          });
        });
      });
    });
  }

  Future<void> _insertMockNote() async {
    int count = await noteDB.noteDao().count() ?? 0;
    if (count > 0) return;
    DateTime now = DateTime.now();
    await noteDB.noteDao().insert(Note(
          text: 'Mock Note 1',
          createDate: now,
          isEdited: false,
          userId: 1,
        ));
    await noteDB.noteDao().bulkInsert([
      Note(
        text: 'Mock Note 1',
        createDate: now,
        isEdited: false,
        userId: 1,
      ),
      Note(
        text: 'Mock Note 2',
        createDate: now,
        isEdited: false,
        userId: 1,
      ),
      Note(
        text: 'Mock Note 3(Embedded)',
        createDate: now,
        isEdited: false,
        address: Address(
          city: 'Tehran',
          street: 'Saei',
          addressName: AddressName(
            name: 'Work',
            flag: true,
          ),
        ),
        userId: 1,
      ),
    ]);
    print('mock notes inserted');
    await noteDB.noteDao().bulkUpdate([
      Note(
        id: 1,
        text: 'Mock Note 1 edited',
        latitude: 1.1,
        createDate: now,
        updateDate: DateTime.now(),
        isEdited: true,
        userId: 1,
      ),
      Note(
        id: 2,
        text: 'Mock Note 2 edited',
        latitude: 1.2,
        createDate: now,
        updateDate: DateTime.now(),
        isEdited: true,
        userId: 1,
      ),
    ]);
    print('mock notes updated');
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _initialized ? 'NoteDB initialized' : 'Initializing NoteDB...',
              style: const TextStyle(fontSize: 20),
            ),
            if (_initialized)
              MaterialButton(
                child: const Text('Go To Notes App'),
                color: Colors.green,
                textColor: Colors.white,
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) => NotesListPage(noteDB),
                  ));
                },
              ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter对象关系映射插件flutter_orm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter对象关系映射插件flutter_orm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用flutter_orm插件进行对象关系映射(ORM)的示例。请注意,flutter_orm可能不是一个真实存在的Flutter插件名称,因此我将以一个假设的ORM插件flutter_orm_example为例来展示如何使用它。如果你使用的是其他具体的ORM插件,请查阅相应的文档并进行调整。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加flutter_orm_example依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_orm_example: ^x.y.z  # 替换为实际版本号

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

2. 定义数据模型

创建一个数据模型类,并使用注解来指定字段和表的关系。

import 'package:flutter_orm_example/annotations.dart';

@Entity(tableName: 'users')
class User {
  @PrimaryKey(autoGenerate: true)
  int? id;

  @Column(name: 'name')
  String name;

  @Column(name: 'email')
  String email;

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

3. 初始化数据库和ORM

在你的应用初始化时,设置数据库和ORM。

import 'package:flutter/material.dart';
import 'package:flutter_orm_example/flutter_orm_example.dart';
import 'package:path_provider/path_provider.dart';
import 'user_model.dart';  // 假设你的数据模型类在这个文件中

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter ORM Example'),
        ),
        body: FutureBuilder<void>(
          future: initDatabase(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              return HomeScreen();
            } else if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            } else {
              return Center(child: Text('Error initializing database'));
            }
          },
        ),
      ),
    );
  }

  Future<void> initDatabase() async {
    // 获取应用文档目录
    final directory = await getApplicationDocumentsDirectory();
    final dbPath = directory.path + '/my_database.db';

    // 初始化ORM
    await FlutterOrm.initialize(dbPath);

    // 注册实体类
    FlutterOrm.registerEntity(User);

    // 创建表(如果尚不存在)
    await FlutterOrm.createAllTables();
  }
}

4. 执行数据库操作

在你的HomeScreen中执行一些数据库操作,比如插入、查询等。

import 'package:flutter/material.dart';
import 'package:flutter_orm_example/flutter_orm_example.dart';
import 'user_model.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late FlutterOrmDatabase db;

  @override
  void initState() {
    super.initState();
    db = FlutterOrm.getDatabase();
  }

  void _insertUser() async {
    final user = User(name: 'John Doe', email: 'john.doe@example.com');
    await db.insert(user);
    print('User inserted with ID: ${user.id}');
  }

  void _queryUsers() async {
    final users = await db.query<User>();
    users.forEach((user) => print('User: ${user.name}, Email: ${user.email}'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _insertUser,
              child: Text('Insert User'),
            ),
            ElevatedButton(
              onPressed: _queryUsers,
              child: Text('Query Users'),
            ),
          ],
        ),
      ),
    );
  }
}

总结

上述代码展示了如何在Flutter项目中使用假设的flutter_orm_example插件进行ORM操作。请注意,实际使用的ORM插件可能会有不同的API和初始化方式,因此请查阅具体插件的文档以获取准确的用法。如果你使用的是特定的ORM插件(如floormoor等),请按照其文档进行相应的配置和操作。

回到顶部