Flutter ObjectBox:API数据模型与本地数据库实体映射问题
ObjectBox 实体映射:API数据转本地存储解决方案
问题背景
现有从API获取的数据模型:
class Product { int id; String name; List<ImageList> images; } class ImageList { String name; String src; }
需要将这些数据存储到ObjectBox,已定义的数据库实体存在构造函数无法处理images字段的问题:
@Entity() class ProductDB { ProductDB({ @Id() int id, String name, images = ToMany<ImageListDB>(), }) } @Entity() class ImageListDB { ImageListDB({ this.name, this.src, }) String name; String src; }
解决方案
1. 修正ObjectBox实体定义
ObjectBox实体必须满足两个核心要求:每个实体要有@Id主键,ToMany关联需在类内直接初始化(不能在构造函数参数中设置默认值)。修正后的实体代码如下:
import 'package:objectbox/objectbox.dart'; @Entity() class ProductDB { @Id() int id; String name; // 直接在类内初始化ToMany关联,由ObjectBox管理 final images = ToMany<ImageListDB>(); ProductDB({ this.id = 0, // id为0表示新实体,ObjectBox会自动分配主键 required this.name, }); } @Entity() class ImageListDB { @Id() int id = 0; // 必须添加主键字段 String? name; String? src; // 可选:添加反向关联,方便从图片实体追溯所属商品 final product = ToOne<ProductDB>(); ImageListDB({ this.name, this.src, }); }
2. 实现API模型到DB实体的映射
通过扩展方法完成API数据模型到ObjectBox实体的转换:
// 给Product类添加扩展方法,快速转换为ProductDB extension ProductToDB on Product { ProductDB toDBEntity() { final productDB = ProductDB(id: id, name: name); // 转换每个ImageList为ImageListDB,并绑定关联关系 final imageDBEntities = images.map((apiImg) { final imgDB = ImageListDB(name: apiImg.name, src: apiImg.src); // 设置反向关联,确保图片和商品绑定 imgDB.product.target = productDB; return imgDB; }).toList(); productDB.images.addAll(imageDBEntities); return productDB; } }
3. 执行本地存储操作
通过ObjectBox的Box实例完成数据存储,关联的ImageListDB会被自动级联存储:
// 假设已初始化ObjectBox Store实例(通常通过全局单例获取) final store = ObjectBox.instance.store; final productBox = store.box<ProductDB>(); // 示例API数据 final apiProduct = Product( id: 1, name: "无线耳机", images: [ ImageList(name: "主图", src: "https://example.com/headphone.jpg"), ImageList(name: "细节图", src: "https://example.com/headphone-detail.jpg"), ], ); // 转换并存储 final productDB = apiProduct.toDBEntity(); productBox.put(productDB);
说明:调用
productBox.put(productDB)时,ObjectBox会自动处理ToMany关联,将所有关联的ImageListDB同步存入数据库,无需单独调用ImageListDB的put方法。
内容的提问来源于stack exchange,提问作者Przemysław Pluszowy
相关产品推荐
相关产品推荐

