How Shopping Cart Persistence Works in the macrozheng/mall E-Commerce System

The macrozheng/mall project persists shopping cart data in MySQL using MyBatis mappers, with the OmsCartItemServiceImpl class orchestrating all database operations through soft-delete logic and duplicate detection.

The shopping cart persistence mechanism in the macrozheng/mall open-source e-commerce platform stores user selections in a relational database to maintain state across sessions. This implementation leverages MyBatis for object-relational mapping and applies a soft-delete pattern via the deleteStatus column, ensuring data integrity while supporting efficient cart lifecycle management.

Architecture Overview

All cart-related persistence logic resides in the portal module and follows a classic service-mapper pattern. The OmsCartItemServiceImpl class in mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java serves as the primary entry point, delegating SQL operations to the OmsCartItemMapper interface generated by MyBatis Generator.

The underlying table oms_cart_item stores individual cart rows with foreign keys to members and products, quantity counts, pricing snapshots, and temporal tracking fields. Every query filters against deleteStatus = 0 to exclude logically deleted entries, enabling recovery capabilities and audit trails.

Adding Items: Insert or Update Logic

When a user adds a product, the system must determine whether to create a new row or increment an existing quantity. The add(OmsCartItem cartItem) method executes this logic by first calling getCartItem to query for an existing entry matching memberId, productId, and productSkuId with deleteStatus = 0.

If no matching row exists, the service inserts a new record capturing the member information, product details, and current timestamp. If the SKU already exists in the cart, the implementation retrieves the existing OmsCartItem, increases its quantity by the new amount, and updates the modifyDate before persisting the change.

// From OmsCartItemServiceImpl.add(...)
OmsCartItem existCartItem = getCartItem(cartItem);
if (existCartItem == null) {
    cartItem.setCreateDate(new Date());
    count = cartItemMapper.insert(cartItem);           // INSERT new row
} else {
    cartItem.setModifyDate(new Date());
    existCartItem.setQuantity(existCartItem.getQuantity() + cartItem.getQuantity());
    count = cartItemMapper.updateByPrimaryKey(existCartItem); // UPDATE quantity
}

This approach prevents duplicate rows for the same SKU while preserving the original createDate and capturing price snapshots at the time of addition.

Retrieving the Cart with Soft-Delete Filtering

The list(Long memberId) method retrieves only active cart items by constructing a MyBatis Example object that explicitly filters for deleteStatus = 0. This ensures that logically deleted items—whether removed individually or cleared in bulk—never appear in the user's active cart view.

// From OmsCartItemServiceImpl.list(...)
OmsCartItemExample example = new OmsCartItemExample();
example.createCriteria()
       .andDeleteStatusEqualTo(0)
       .andMemberIdEqualTo(memberId);
return cartItemMapper.selectByExample(example);

The returned List<OmsCartItem> contains fully populated entities including product references, quantities, and pricing data required for checkout calculations.

Updating Item Quantities

Cart quantity modifications use selective updates to minimize database traffic. The updateQuantity(Long id, Long memberId, Integer quantity) method creates a target object containing only the new quantity, then applies it through updateByExampleSelective with a strict criteria match on id, memberId, and deleteStatus = 0.

// From OmsCartItemServiceImpl.updateQuantity(...)
OmsCartItem cartItem = new OmsCartItem();
cartItem.setQuantity(quantity);
OmsCartItemExample example = new OmsCartItemExample();
example.createCriteria()
       .andDeleteStatusEqualTo(0)
       .andIdEqualTo(id)
       .andMemberIdEqualTo(memberId);
return cartItemMapper.updateByExampleSelective(cartItem, example);

This pattern ensures that only the specific column changes, the row belongs to the requesting member, and the item has not been previously soft-deleted.

Deletion and Cart Clearing via Soft-Delete

Rather than executing physical DELETE statements, the implementation sets deleteStatus = 1 to mark rows as removed. The delete(Long memberId, List<Long> ids) method updates multiple rows simultaneously by matching against the member ID and a list of cart item IDs.

// From OmsCartItemServiceImpl.delete(...)
OmsCartItem record = new OmsCartItem();
record.setDeleteStatus(1);
OmsCartItemExample example = new OmsCartItemExample();
example.createCriteria().andIdIn(ids).andMemberIdEqualTo(memberId);
return cartItemMapper.updateByExampleSelective(record, example);

The clear(Long memberId) operation follows the same pattern but omits the ID list, effectively marking every cart row for that member as deleted:

// From OmsCartItemServiceImpl.clear(...)
OmsCartItem record = new OmsCartItem();
record.setDeleteStatus(1);
OmsCartItemExample example = new OmsCartItemExample();
example.createCriteria().andMemberIdEqualTo(memberId);
return cartItemMapper.updateByExampleSelective(record, example);

Database Schema and Entity Model

The OmsCartItem entity in mall-mbg/src/main/java/com/macro/mall/model/OmsCartItem.java maps directly to the oms_cart_item table with the following critical persistence fields:

  • id: Primary key for the cart row
  • member_id: Foreign key linking the cart to the user account
  • product_id and product_sku_id: References to the product catalog and specific SKU variants
  • quantity: Integer count of units requested
  • price: Decimal unit price captured at the time of addition to handle future price changes
  • delete_status: Soft-delete flag where 0 indicates active and 1 indicates removed
  • create_date and modify_date: Timestamps for audit tracking

The MyBatis mapper interface OmsCartItemMapper provides standard CRUD methods including insert, selectByExample, updateByPrimaryKey, and updateByExampleSelective, with SQL generated automatically by MyBatis Generator.

Integration with Order Creation

During checkout, the OmsPortalOrderServiceImpl class interacts with the cart persistence layer through two critical phases. First, it calls listPromotion to retrieve cart items enriched with promotion calculations. After successful order persistence, it invokes deleteCartItemList to clear the cart, which internally executes the soft-delete logic described above, ensuring the cart reflects the post-purchase state without losing historical data.

Summary

  • Shopping cart persistence in macrozheng/mall uses MySQL with MyBatis mappers, centered on the OmsCartItemServiceImpl service class.
  • Duplicate detection during item addition merges quantities for existing SKUs rather than creating redundant rows.
  • Soft-delete architecture uses the deleteStatus column (0 for active, 1 for deleted) to preserve data integrity and enable audit capabilities.
  • Security boundaries ensure all queries filter by both memberId and deleteStatus, preventing cross-user data leakage and exposing only valid cart items.
  • Order workflow integration automatically clears the cart via soft-delete after successful checkout through OmsPortalOrderServiceImpl.

Frequently Asked Questions

Where is the shopping cart data physically stored in the mall project?

The data persists in the oms_cart_item table within a MySQL database, accessed through the MyBatis mapper interface OmsCartItemMapper and managed by the service implementation OmsCartItemServiceImpl in the portal module.

How does the system prevent duplicate product entries in the same cart?

Before inserting a new row, the add method queries for an existing item matching the memberId, productId, and productSkuId with deleteStatus = 0. If found, it increments the existing quantity via updateByPrimaryKey; otherwise, it inserts a new record via cartItemMapper.insert.

What is the purpose of the deleteStatus field in the cart table?

The deleteStatus column implements a soft-delete pattern where 0 indicates an active cart item and 1 marks it as deleted. This approach preserves historical cart data for potential recovery or analytics while ensuring deleted items never appear in active cart queries through the andDeleteStatusEqualTo(0) criteria.

How is the shopping cart cleared after a user places an order?

After order generation succeeds, OmsPortalOrderServiceImpl calls the cart service's deletion methods, which execute updateByExampleSelective to set deleteStatus = 1 for all rows matching the member ID, effectively clearing the cart without removing the underlying database records.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →