基于SSM框架的在线蛋糕销售商城系统技术解析
项目背景与业务价值
在传统烘焙行业数字化转型的浪潮中,"甜蜜时光"在线蛋糕商城应运而生。该系统针对传统蛋糕店面临的营业时间限制、地域覆盖局限、手工管理效率低下等痛点,构建了一个完整的线上销售解决方案。通过将商品展示、库存管理、在线交易、订单处理等核心业务流程数字化,显著提升了商家的运营效率和消费者的购物体验。
技术架构设计
系统采用经典的SSM(Spring + Spring MVC + MyBatis)框架组合,遵循MVC设计模式,实现了清晰的分层架构:
表现层:基于Spring MVC框架,通过@Controller注解的控制器类处理前端请求,实现请求路由、参数绑定和数据验证。RESTful风格的API设计确保了接口的规范性和可维护性。
业务逻辑层:Spring框架作为核心容器,通过依赖注入管理Service组件的生命周期。利用Spring的声明式事务管理,确保订单创建、库存扣减等关键业务操作的原子性。
数据持久层:MyBatis框架负责数据库操作,通过Mapper接口和XML映射文件实现对象关系映射。动态SQL的支持使得复杂查询条件的构建更加灵活。
数据库设计深度解析
用户表设计
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
phone VARCHAR(20),
address TEXT,
role ENUM('admin', 'customer') DEFAULT 'customer',
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login_time TIMESTAMP,
status TINYINT DEFAULT 1
);
用户表采用纵向扩展设计,包含完整的用户身份信息和权限管理字段。password字段使用BCrypt加密存储,确保安全性。role字段通过枚举类型实现角色权限控制,created_time和last_login_time时间戳为用户行为分析提供数据支持。
商品信息表设计
CREATE TABLE cakes (
cake_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
category_id INT,
image_url VARCHAR(200),
stock_quantity INT DEFAULT 0,
sales_volume INT DEFAULT 0,
status TINYINT DEFAULT 1,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(category_id)
);
商品表设计体现了电商系统的核心需求:price字段使用DECIMAL类型确保金额计算的精确性;stock_quantity实现库存管理;sales_volume为销售分析提供数据基础;updated_time字段通过ON UPDATE CURRENT_TIMESTAMP自动维护更新时间。
订单表设计
CREATE TABLE orders (
order_id VARCHAR(32) PRIMARY KEY,
user_id INT NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status ENUM('pending', 'paid', 'shipped', 'completed', 'cancelled') DEFAULT 'pending',
shipping_address TEXT NOT NULL,
payment_method VARCHAR(20),
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
paid_time TIMESTAMP,
completed_time TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
订单表采用业务主键设计,order_id使用UUID确保分布式环境下的唯一性。status字段通过枚举类型清晰定义订单生命周期,多个时间戳字段完整记录订单状态流转过程,为订单跟踪和统计分析提供完整数据支持。
核心功能实现解析
用户认证与权限管理
系统实现基于角色的访问控制机制,通过Spring Security框架实现安全认证:
@Component
public class JwtTokenProvider {
private String secretKey = "cakeMallSecretKey";
private long validityInMilliseconds = 3600000; // 1小时
public String createToken(String username, List<Role> roles) {
Claims claims = Jwts.claims().setSubject(username);
claims.put("auth", roles.stream()
.map(Role::getAuthority)
.collect(Collectors.toList()));
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
throw new InvalidJwtAuthenticationException("Expired or invalid JWT token");
}
}
}

商品浏览与搜索功能
商品展示模块实现分类浏览、关键词搜索、价格排序等核心功能:
@Controller
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public String listProducts(
@RequestParam(value = "category", required = false) Integer categoryId,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "minPrice", required = false) Double minPrice,
@RequestParam(value = "maxPrice", required = false) Double maxPrice,
@RequestParam(value = "sort", defaultValue = "created_time") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@RequestParam(value = "page", defaultValue = "1") int page,
Model model) {
ProductQuery query = new ProductQuery();
query.setCategoryId(categoryId);
query.setKeyword(keyword);
query.setMinPrice(minPrice);
query.setMaxPrice(maxPrice);
query.setSortField(sort);
query.setSortOrder(order);
query.setPageSize(12);
query.setCurrentPage(page);
PageInfo<Product> pageInfo = productService.getProductsByQuery(query);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("query", query);
return "product/list";
}
@GetMapping("/{id}")
public String productDetail(@PathVariable("id") Integer productId, Model model) {
Product product = productService.getProductById(productId);
if (product == null) {
throw new ResourceNotFoundException("商品不存在");
}
model.addAttribute("product", product);
return "product/detail";
}
}

购物车与订单管理
购物车功能支持商品添加、数量修改、批量删除等操作,订单处理实现完整的业务流程:
@Service
@Transactional
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private ProductMapper productMapper;
@Override
public Order createOrder(OrderCreateRequest request) {
// 验证库存
for (CartItem item : request.getItems()) {
Product product = productMapper.selectById(item.getProductId());
if (product.getStockQuantity() < item.getQuantity()) {
throw new InsufficientStockException("商品库存不足: " + product.getName());
}
}
// 创建订单
Order order = new Order();
order.setOrderId(generateOrderId());
order.setUserId(request.getUserId());
order.setTotalAmount(calculateTotalAmount(request.getItems()));
order.setShippingAddress(request.getShippingAddress());
order.setStatus(OrderStatus.PENDING);
orderMapper.insert(order);
// 创建订单项并扣减库存
for (CartItem item : request.getItems()) {
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getOrderId());
orderItem.setProductId(item.getProductId());
orderItem.setQuantity(item.getQuantity());
orderItem.setUnitPrice(item.getUnitPrice());
orderItemMapper.insert(orderItem);
// 扣减库存
productMapper.decreaseStock(item.getProductId(), item.getQuantity());
}
return order;
}
private String generateOrderId() {
return "ORD" + System.currentTimeMillis() +
String.format("%04d", new Random().nextInt(10000));
}
private BigDecimal calculateTotalAmount(List<CartItem> items) {
return items.stream()
.map(item -> item.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}

后台管理系统
管理员后台提供完整的商品管理、订单处理、用户管理等功能:
@RestController
@RequestMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public class AdminController {
@Autowired
private ProductService productService;
@PostMapping("/products")
public ResponseEntity<?> createProduct(@Valid @RequestBody ProductCreateRequest request) {
Product product = productService.createProduct(request);
return ResponseEntity.ok(ApiResponse.success("商品创建成功", product));
}
@PutMapping("/products/{id}")
public ResponseEntity<?> updateProduct(@PathVariable Integer id,
@Valid @RequestBody ProductUpdateRequest request) {
Product product = productService.updateProduct(id, request);
return ResponseEntity.ok(ApiResponse.success("商品更新成功", product));
}
@GetMapping("/orders")
public ResponseEntity<?> getOrders(
@RequestParam(value = "status", required = false) OrderStatus status,
@RequestParam(value = "page", defaultValue = "1") int page) {
OrderQuery query = new OrderQuery();
query.setStatus(status);
query.setPageSize(20);
query.setCurrentPage(page);
PageInfo<Order> pageInfo = orderService.getOrdersByQuery(query);
return ResponseEntity.ok(ApiResponse.success(pageInfo));
}
@PutMapping("/orders/{orderId}/status")
public ResponseEntity<?> updateOrderStatus(@PathVariable String orderId,
@RequestParam OrderStatus status) {
orderService.updateOrderStatus(orderId, status);
return ResponseEntity.ok(ApiResponse.success("订单状态更新成功"));
}
}

实体模型设计
系统采用面向对象的设计思想,核心实体模型之间通过明确的关联关系构建完整的业务模型:
// 商品实体
@Entity
@Table(name = "cakes")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer productId;
private String name;
private String description;
private BigDecimal price;
@ManyToOne
@JoinColumn(name = "category_id")
private Category category;
private String imageUrl;
private Integer stockQuantity;
private Integer salesVolume;
private Boolean status;
private Date createdTime;
private Date updatedTime;
// 省略getter/setter方法
}
// 订单实体
@Entity
@Table(name = "orders")
public class Order {
@Id
private String orderId;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
private BigDecimal totalAmount;
@Enumerated(EnumType.STRING)
private OrderStatus status;
private String shippingAddress;
private String paymentMethod;
private Date createdTime;
private Date paidTime;
private Date completedTime;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> items;
// 省略getter/setter方法
}
性能优化策略
数据库查询优化
系统通过MyBatis的二级缓存、查询结果分页、延迟加载等机制优化数据库访问性能:
<!-- 商品查询Mapper配置 -->
<mapper namespace="com.cakemall.mapper.ProductMapper">
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
<select id="selectByQuery" parameterType="ProductQuery" resultMap="ProductResultMap">
SELECT
p.product_id, p.name, p.description, p.price,
p.image_url, p.stock_quantity, p.sales_volume,
c.category_id, c.category_name
FROM cakes p
LEFT JOIN categories c ON p.category_id = c.category_id
<where>
p.status = 1
<if test="categoryId != null">
AND p.category_id = #{categoryId}
</if>
<if test="keyword != null and keyword != ''">
AND (p.name LIKE CONCAT('%', #{keyword}, '%')
OR p.description LIKE CONCAT('%', #{keyword}, '%'))
</if>
<if test="minPrice != null">
AND p.price >= #{minPrice}
</if>
<if test="maxPrice != null">
AND p.price <= #{maxPrice}
</if>
</where>
ORDER BY
<choose>
<when test="sortField == 'price'">p.price</when>
<when test="sortField == 'sales'">p.sales_volume</when>
<otherwise>p.created_time</otherwise>
</choose>
<choose>
<when test="sortOrder == 'asc'">ASC</when>
<otherwise>DESC</otherwise>
</choose>
LIMIT #{offset}, #{pageSize}
</select>
</mapper>
未来优化方向
1. 微服务架构改造
将单体应用拆分为商品服务、订单服务、用户服务等独立微服务,通过Spring Cloud实现服务治理、配置管理和负载均衡。
2. 弹性搜索集成
引入Elasticsearch替代数据库模糊查询,实现商品搜索的全文检索、拼音搜索、同义词扩展等高级搜索功能。
3. 分布式缓存优化
使用Redis集群实现分布式会话管理、热点数据缓存、购物车数据持久化,提升系统并发处理能力。
4. 消息队列应用
通过RabbitMQ或Kafka实现订单创建、库存扣减、消息通知等业务的异步处理,提高系统响应速度和可靠性。
5. 移动端应用开发
开发React Native或Flutter跨平台移动应用,提供更优化的移动购物体验,支持推送通知、地理位置服务等移动端特性。
"甜蜜时光"蛋糕商城系统通过SSM框架的成熟技术组合,构建了稳定可靠的电商平台基础。系统架构清晰、功能完整,为后续的技术演进和业务扩展奠定了坚实基础。随着业务规模的扩大和技术栈的升级,系统将持续优化以适应更高的性能要求和更复杂的业务场景。