Flutter使用Floor数据库关联购物车与商品表时,仅能添加productId为1的商品到购物车的问题排查
Flutter使用Floor数据库关联购物车与商品表时,仅能添加productId为1的商品到购物车的问题排查
嘿,我来帮你一步步排查这个诡异的问题,咱们从你提供的代码片段逐个模块梳理:
1. Floor DAO 层关联查询代码
先看购物车和商品表的关联查询逻辑:
@Query(''' SELECT c.cartId AS cartId, c.userId AS userId, c.productId AS productId, c.quantity AS quantity, p.title AS title, p.price AS price, p.thumbnail AS thumbnail FROM CartEntity c INNER JOIN ProductEntity p ON c.productId = p.productId WHERE c.userId = :userId ''') Future<List<CartWithProduct>> getCartWithProduct(int userId);
排查点:
- 确认
CartEntity和ProductEntity的productId字段是完全相同的数据类型(比如都是int),类型不匹配会导致关联失败,可能只有productId=1刚好侥幸匹配;- 注意这里用的是
INNER JOIN——如果ProductEntity里没有对应productId的商品记录,这条购物车项会被直接过滤掉,你会误以为没添加成功,实际数据库里可能已经存在CartEntity记录。
2. Floor 服务层代码
这层是DAO的直接封装,逻辑本身没问题:
Future<List<CartWithProduct>> getCartWithProduct(int userId) async { return await cartDao.getCartWithProduct(userId); }
3. GetX 控制器核心添加购物车逻辑
这是问题高发区,咱们逐行看:
Future<bool> addToCart() async { print("-------------add to cart------------------"); try { final userId = await getCurrentUserId(); print('userId=$userId, productId=${product.productId}'); final existing = await _cartFloorService.getCart( userId, product.productId, ); if (existing == null) { print("no existing item found."); } else { print("existing item: ${existing.toJson()}"); } if (existing != null) { final updatedCart = Cart( existing.cartId, existing.productId, existing.userId, existing.quantity + 1, ); print("-------------------updated cart---------------"); await _cartFloorService.updateCartItem(updatedCart); print(updatedCart.toJson()); print("-----------------------------------------------"); } else { final newCartItem = Cart( null, product.productId, userId, product.quantity, ); print("product id: ${product.productId},quantity: ${product.quantity}"); print("-------------------------------------"); int inserted = await _cartFloorService.insertCart(newCartItem); print("----------returned value of insertCart----------"); print(inserted); print("------------------------------------------------"); newCartItem.cartId = inserted; print("-----------------cart details-------------------"); print(newCartItem.toJson()); } return true; } catch (e) { print('Error adding to cart: $e'); return false; } }
重点排查:
getCart(userId, productId)方法的实现:你没提供这个方法的代码,但它是判断购物车项是否存在的核心!如果这个方法的@Query条件写错了(比如把productId硬写成1、字段名拼写错误),就会永远只能查到productId=1的项,其他商品的判断逻辑全乱;- userId的一致性:添加不同商品时,打印的
userId是否完全一致?比如添加productId=1时userId是1,添加productId=2时userId变成0,那后续查询会过滤掉userId不匹配的项;- 新商品的
product.quantity:打印的quantity: ${product.quantity}是否为1?如果这个值是0,插入后可能因为quantity为0在关联查询中被忽略;- insertCart的返回值:添加其他productId时,
inserted是否>0?如果是0说明插入失败,要检查CartEntity的主键配置(比如cartId是否设置了@PrimaryKey(autoGenerate: true))。
4. GetX 控制器购物车列表获取逻辑
Future<void> getCartItems() async { print("---------get cart items---------------------"); final prefs = await SharedPreferences.getInstance(); final userId = prefs.getInt('currentUserId') ?? 0; print(' current userId: $userId'); final cartItems = await _cartFloorService.getCartWithProduct(userId); print('cart items fetched: ${cartItems.length}'); for (var i in cartItems) { print( "----------------------------Cart Product--------------------------------", ); print( ' ---- product: ${i.title}, Qty: ${i.quantity}, Price: ${i.price} ----', ); print( "---------------------------------------------------------------------", ); } cartList.assignAll(cartItems); }
排查点:
- 这里的
currentUserId是从SharedPreferences取的,和addToCart里的getCurrentUserId()是否是同一逻辑?如果两个地方取的userId不一致,会导致查询不到其他商品的购物车项;- 把DAO的
INNER JOIN改成LEFT JOIN测试:如果改成LEFT JOIN后能看到其他productId的项,说明问题出在ProductEntity没有对应商品记录,INNER JOIN过滤掉了这些项。
5. Cart 模型与实体转换代码
import 'dart:convert'; import '../local_db/entities/cart_entity.dart'; class Cart { int? cartId; int productId = 0; int userId = 0; int quantity = 1; Cart(this.cartId, this.productId, this.userId, this.quantity); Cart.empty(); Cart.fromJson(Map<String, dynamic> json) { cartId = json['cartId'] ?? 0; productId = json['productId'] ?? 0; userId = json['userId'] ?? 0; quantity = json['quantity'] ?? 1; } Map<String, dynamic> toJson() { return { 'cartId': cartId, 'productId': productId, 'userId': userId, 'quantity': quantity, }; } Cart.fromEntity(CartEntity entity) { cartId = entity.cartId; productId = entity.productId; userId = entity.userId; quantity = entity.quantity; } CartEntity toEntity() { // 确认这个方法的实现是否正确,比如是否正确传递productId return CartEntity( cartId: cartId, productId: productId, userId: userId, quantity: quantity, ); } }
排查点:
toEntity()方法是否正确把productId传递给CartEntity?如果这里被错误赋值为1,所有插入的购物车项productId都会是1。
最后几个关键验证步骤
- 直接查看数据库:用Android Studio的Database Inspector打开App数据库,查看
CartEntity表是否有其他productId的记录; - 测试LEFT JOIN:把DAO的
INNER JOIN改成LEFT JOIN,如果能看到其他productId的项,就是ProductEntity缺少对应记录; - 检查getCart方法:务必确认
_cartFloorService.getCart(userId, productId)的@Query是SELECT * FROM CartEntity WHERE userId = :userId AND productId = :productId,没有硬编码或拼写错误。
内容来源于stack exchange
相关产品推荐
相关产品推荐

