如何在Isar中向嵌套列表添加数据?附场景与模型示例
Isar数据库操作解决方案
一、向Training的嵌套List添加数据
因为Exercise是用@embedded标记的嵌入式对象,它会和Training对象一同存储。要添加新的Exercise,只需找到目标Training实例,更新其exercises列表后,将整个Training对象重新存入Isar即可。
具体实现代码
// 假设已初始化Isar实例,命名为isar await isar.writeTxn(() async { // 通过ID获取要修改的Training final targetTraining = await isar.trainings.get(targetTrainingId); if (targetTraining != null) { // 创建新的Exercise实例 final newExercise = Exercise( title: "杠铃卧推", sets: 4, reps: 12, weight: 60, description: "下沉时肘部与肩同高" ); // 将Exercise添加到目标Training的列表中 targetTraining.exercises.add(newExercise); // 更新Isar中的Training记录 await isar.trainings.put(targetTraining); } });
注意事项
- 必须在**写事务(writeTxn)**中执行修改操作,保证数据一致性
- 如果需要批量添加多个Exercise,可一次性添加到列表后再执行
put操作,减少数据库交互次数
二、是否要将Training和Exercise设为独立集合并关联?
这取决于你的业务需求,两种方案的优缺点如下:
当前嵌入式方案(推荐当前场景)
优点
- 数据耦合度高,查询Training时可直接获取所有关联的Exercise,无需额外查询
- 操作逻辑简单,无需处理复杂的引用关系
- 适合Exercise完全依附于Training的场景(比如删除Training时,关联的Exercise也需一并删除,且Exercise不会被其他Training复用)
缺点
- 当Exercise数量极大时,每次更新Training都需要序列化整个列表,可能影响性能
- 无法单独查询、修改某一个Exercise,必须通过对应的Training操作
独立集合+关联方案
如果后续需要单独操作Exercise(比如查询所有包含“卧推”的训练任务),或Exercise数据量较大,可以改为独立集合,用Isar的关联功能实现:
修改后的模型代码
@collection class Training { Training(this.title, this.weekDay); Id id = Isar.autoIncrement; String title; String weekDay; // 关联多个Exercise final exercises = IsarLinks<Exercise>(); } @collection class Exercise { Exercise({ this.title, this.sets, this.reps, this.weight, this.time, this.description }); Id id = Isar.autoIncrement; String? title; int? sets; int? reps; int? weight; String? time; String? description; // 反向关联所属的Training(可选) final training = IsarLink<Training>(); }
优点
- 可单独查询、更新Exercise,无需修改Training对象
- 数据量大时性能更优,不需要每次序列化整个Exercise列表
- 支持Exercise被多个Training引用(如果业务需要)
缺点
- 操作逻辑更复杂,添加Exercise时需要维护关联关系
- 查询Training时需显式加载关联的Exercise(比如使用
.include('exercises'))
结论
如果你的业务场景中,Exercise是Training的专属子任务,不会独立存在或被复用,那么当前的嵌入式方案更简单高效。只有当需要单独操作Exercise或数据量较大时,才考虑改为独立集合+关联的方式。
内容的提问来源于stack exchange,提问作者Moler32
相关产品推荐
相关产品推荐

