You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用Drift时如何实现数据库与模型的映射?

最佳数据映射方案(Drift + SQLite)

针对你提到的「避免手动重复映射、Model与数据库解耦」的需求,以下是几种实用的解决方案,按推荐优先级排序:

1. 专用映射器类(最推荐,解耦彻底)

创建独立的映射器类,专门负责DataClass(Drift生成)与ModelClass(自定义业务模型)之间的转换逻辑。这种方式完全隔离了业务模型与数据库实现,符合单一职责原则,也便于集中维护映射规则。

示例代码:

// 映射器类:仅处理数据转换,不涉及业务或数据库操作
class TodoMapper {
  // 将Drift生成的DataClass转为业务Model
  static TodoModel toModel(TodoData data) {
    return TodoModel(
      id: data.id,
      title: data.title,
      isCompleted: data.isCompleted,
      dueDate: data.dueDate,
    );
  }

  // 将业务Model转为Drift的DataClass
  static TodoData toData(TodoModel model) {
    return TodoData(
      id: model.id,
      title: model.title,
      isCompleted: model.isCompleted,
      dueDate: model.dueDate,
    );
  }

  // 批量转换(避免重复写map逻辑)
  static List<TodoModel> toModelList(List<TodoData> dataList) {
    return dataList.map(toModel).toList();
  }
}

在Repository中使用:

class TodoRepository {
  final MyDatabase _db;

  TodoRepository(this._db);

  Future<List<TodoModel>> getTodos() async {
    final dataList = await _db.select(_db.todos).get();
    // 调用映射器批量转换
    return TodoMapper.toModelList(dataList);
  }

  Future<void> addTodo(TodoModel model) async {
    final data = TodoMapper.toData(model);
    await _db.into(_db.todos).insert(data);
  }
}

优点:业务Model完全无需知晓数据库细节,映射逻辑集中管理,修改或新增规则只需改动映射器,不易出错。
缺点:需要额外编写映射器类,但这是合理的分层开销。

2. 扩展方法(轻量简洁,适合小型项目)

给Drift生成的DataClass和自定义ModelClass添加扩展方法,实现快速转换。这种方式代码更简洁,且不会污染Model本身的代码。

示例代码:

// 给Drift的TodoData添加转Model的扩展
extension TodoDataExt on TodoData {
  TodoModel toModel() {
    return TodoModel(
      id: id,
      title: title,
      isCompleted: isCompleted,
      dueDate: dueDate,
    );
  }
}

// 给自定义Model添加转DataClass的扩展
extension TodoModelExt on TodoModel {
  TodoData toData() {
    return TodoData(
      id: id,
      title: title,
      isCompleted: isCompleted,
      dueDate: dueDate,
    );
  }
}

Repository中使用:

Future<List<TodoModel>> getTodos() async {
  final dataList = await _db.select(_db.todos).get();
  return dataList.map((data) => data.toModel()).toList();
}

优点:代码简洁,无需额外类,开发效率高。
缺点:扩展方法可能分散在多个文件中,大型项目维护起来不如集中式映射器方便。

3. TypeConverter(仅适合字段级转换,不推荐对象级映射)

Drift的TypeConverter设计初衷是处理单个字段的类型适配(比如将枚举转成数据库支持的int/String、DateTime转成时间戳等),而非整个对象的映射。如果强行用它来做DataClass到ModelClass的转换,会导致Model与Drift产生耦合,违背你「解耦」的需求,因此不推荐在这个场景使用。


内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:52:32