Flutter使用ObjectBox的putMany方法时如何实现多实体关联单实体
Flutter ObjectBox 单实体关联多实体一次putMany批量写入方案
ObjectBox原生支持对象图级联持久化,不需要提前获取关联目标的ID、不需要分多次调用写入方法,只要在内存中完成关联关系绑定,单次putMany即可完成全部数据(含关联目标、所有关联实体)的写入和关联关系维护。
核心实现逻辑
这是典型的多对一关联场景:N个实体指向同一个目标实体,实现步骤非常简单:
- 先在内存中创建作为关联目标的单个实体实例,不需要手动为其赋值ID
- 创建所有需要关联该目标的实体实例,将每个实例的
ToOne关联字段的target指向同一个目标实体内存实例 - 直接调用关联实体对应Box的
putMany方法传入所有关联实体列表即可,ObjectBox会自动在单事务内完成:- 检测到关联的目标实体是未入库的新对象,优先写入目标实体拿到自增ID
- 将目标实体的ID自动回填到所有关联实体的外键字段
- 批量写入所有关联实体,全程不需要额外手动操作
代码示例
首先定义实体,注意用ToOne描述单实体关联关系:
// 作为关联目标的单个实体:比如商品分类 @Entity() class Category { int id = 0; String categoryName; Category(this.categoryName); } // 关联目标的多份实体:比如具体商品 @Entity() class Product { int id = 0; String productName; double price; // 声明对Category的单对象关联 final category = ToOne<Category>(); Product(this.productName, this.price); }
批量写入逻辑,全程仅调用一次putMany:
// 1. 内存中创建唯一的关联目标实例 final digitalCategory = Category("数码配件"); // 2. 创建所有商品,全部绑定同一个分类实例 final products = [ Product("钢化膜", 19.9)..category.target = digitalCategory, Product("20W快充头", 39.9)..category.target = digitalCategory, Product("入耳式无线耳机", 179.9)..category.target = digitalCategory, Product("手机壳", 29.9)..category.target = digitalCategory, // 后续新增的商品都按同样方式绑定同一个digitalCategory即可 ]; // 3. 单次调用putMany完成全部写入,不需要提前写入分类 // 级联保存会自动处理分类的写入和外键关联 final store = StoreProvider.of<AppState>(context).store; store.box<Product>().putMany(products);
注意事项
- 所有关联实体必须绑定同一个内存中的目标实例,如果给不同商品绑定内容完全相同但分别实例化的Category对象,会导致重复插入多条分类记录
- 如果是关联数据库中已经存在的目标实体,直接查询出该实体实例后赋值给
ToOne.target即可,不会重复插入目标实体 - 如果是一对多反向关联(目标实体中用
ToMany<Product>持有所有关联实体),逻辑完全一致:把所有商品实例加入目标实体的ToMany列表后,哪怕只调用put写入单个目标实体,也会自动级联写入所有关联的商品,不需要额外调用putMany - 整个写入过程是单事务批量执行,性能和写入同类型实体的
putMany完全一致,不会因为级联保存出现额外的性能损耗
内容的提问来源于stack exchange,提问作者TRI NI TY
相关产品推荐
相关产品推荐

