随着餐饮行业数字化转型的加速,传统电话订餐模式显露出诸多局限性:订单信息易错漏、高峰期处理能力不足、人工管理成本高昂。针对这些痛点,我们设计并实现了一套基于SSM(Spring + Spring MVC + MyBatis)架构的智能餐饮订购系统,为中小型餐饮企业提供完整的线上运营解决方案。
该系统采用经典的三层架构设计,通过Spring框架实现业务对象的依赖注入和声明式事务管理,确保订单、支付等核心操作的数据一致性。Spring MVC模块负责Web请求的路由分发和参数绑定,而MyBatis作为持久层框架,利用其动态SQL特性高效处理复杂的多条件查询。前端采用JSP结合jQuery技术,实现购物车实时更新、表单验证等交互功能。
数据库设计体现业务逻辑深度 系统共设计16张数据表,其中订单主表(orders)的结构充分体现了业务复杂性:
CREATE TABLE orders (
order_id VARCHAR(32) PRIMARY KEY,
user_id INT NOT NULL,
merchant_id INT NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
order_status TINYINT NOT NULL COMMENT '0-待支付 1-已支付 2-配送中 3-已完成',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
pay_time DATETIME,
delivery_address TEXT NOT NULL,
INDEX idx_user_id (user_id),
INDEX idx_merchant_id (merchant_id),
INDEX idx_create_time (create_time)
);
该表通过状态字段实现订单生命周期管理,同时建立多维度索引优化查询性能。金额字段采用DECIMAL类型确保计算精度,时间戳字段完整记录业务节点。
菜品信息表(dish)的设计支持灵活的营销策略:
CREATE TABLE dish (
dish_id INT PRIMARY KEY AUTO_INCREMENT,
dish_name VARCHAR(100) NOT NULL,
category_id INT NOT NULL,
price DECIMAL(8,2) NOT NULL,
original_price DECIMAL(8,2) COMMENT '原价用于折扣显示',
stock INT DEFAULT 0,
image_url VARCHAR(200),
description TEXT,
is_available TINYINT DEFAULT 1,
sales_count INT DEFAULT 0
);
通过原价与现价字段组合支持促销活动,销量计数器为热门菜品推荐提供数据支撑。库存字段与订单系统联动实现实时扣减,避免超卖情况。
核心功能模块实现解析
- 智能购物车系统 前端通过jQuery实现动态交互,后端采用Redis缓存用户购物车数据:
@Service
public class CartServiceImpl implements CartService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void addToCart(String userId, CartItem item) {
String key = "cart:" + userId;
BoundHashOperations<String, Object, Object> hashOps =
redisTemplate.boundHashOps(key);
// 存在则数量累加,否则新增条目
if(hashOps.hasKey(item.getDishId())) {
CartItem existing = (CartItem) hashOps.get(item.getDishId());
existing.setQuantity(existing.getQuantity() + item.getQuantity());
hashOps.put(item.getDishId(), existing);
} else {
hashOps.put(item.getDishId(), item);
}
// 设置24小时过期时间
redisTemplate.expire(key, 24, TimeUnit.HOURS);
}
}

- 分布式订单处理 订单服务采用Spring声明式事务管理,确保数据一致性:
@Transactional
@Service
public class OrderServiceImpl implements OrderService {
public String createOrder(OrderDTO orderDTO) {
// 1. 校验库存
for(OrderItem item : orderDTO.getItems()) {
Dish dish = dishMapper.selectByPrimaryKey(item.getDishId());
if(dish.getStock() < item.getQuantity()) {
throw new BusinessException("库存不足");
}
}
// 2. 生成订单号(雪花算法)
String orderId = IdGenerator.nextId();
// 3. 扣减库存
for(OrderItem item : orderDTO.getItems()) {
dishMapper.reduceStock(item.getDishId(), item.getQuantity());
}
// 4. 插入订单记录
Orders order = buildOrder(orderDTO, orderId);
orderMapper.insert(order);
return orderId;
}
}

- 多条件菜品检索 MyBatis动态SQL构建灵活查询:
<select id="selectByConditions" resultMap="BaseResultMap">
SELECT * FROM dish
<where>
is_available = 1
<if test="categoryId != null">
AND category_id = #{categoryId}
</if>
<if test="minPrice != null">
AND price >= #{minPrice}
</if>
<if test="maxPrice != null">
AND price <= #{maxPrice}
</if>
<if test="keyword != null and keyword != ''">
AND (dish_name LIKE CONCAT('%',#{keyword},'%')
OR description LIKE CONCAT('%',#{keyword},'%'))
</if>
</where>
<choose>
<when test="sortType == 'price_asc'">
ORDER BY price ASC
</when>
<when test="sortType == 'sales_desc'">
ORDER BY sales_count DESC
</when>
<otherwise>
ORDER BY create_time DESC
</otherwise>
</choose>
</select>

- RBAC权限控制系统 Spring Security实现多角色访问控制:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/merchant/**").hasAnyRole("MERCHANT", "ADMIN")
.antMatchers("/user/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.successHandler(customSuccessHandler)
.and()
.logout()
.logoutSuccessUrl("/");
}
}
- 实时消息推送 WebSocket实现订单状态实时通知:
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketServer {
private static ConcurrentHashMap<String, Session> sessions =
new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
sessions.put(userId, session);
}
public void sendMessage(String userId, String message) {
Session session = sessions.get(userId);
if(session != null && session.isOpen()) {
session.getAsyncRemote().sendText(message);
}
}
}

- 数据统计分析 MyBatis注解方式实现复杂统计查询:
@Mapper
public interface StatisticsMapper {
@Select("SELECT DATE(create_time) as date, COUNT(*) as orderCount, " +
"SUM(total_amount) as totalAmount FROM orders " +
"WHERE create_time >= #{startDate} AND create_time <= #{endDate} " +
"GROUP BY DATE(create_time)")
List<OrderStatistics> getDailyStatistics(@Param("startDate") Date startDate,
@Param("endDate") Date endDate);
}

实体模型设计精要 订单实体与DTO设计体现领域驱动设计思想:
@Data
public class OrderDTO {
private Integer userId;
private Integer merchantId;
private String deliveryAddress;
private List<OrderItem> items;
@Data
public static class OrderItem {
private Integer dishId;
private String dishName;
private BigDecimal price;
private Integer quantity;
}
}
@Entity
@Table(name = "orders")
public class Orders {
@Id
private String orderId;
private Integer userId;
private BigDecimal totalAmount;
private OrderStatus orderStatus;
public enum OrderStatus {
PENDING_PAYMENT, PAID, DELIVERING, COMPLETED
}
}
系统优化方向
- 缓存策略升级:引入多级缓存架构,本地缓存结合分布式Redis,对热点菜品数据实施差异化过期策略
- 订单分库分表:按时间维度进行订单表水平拆分,采用Sharding-JDBC中间件实现透明路由
- 异步处理优化:使用RabbitMQ消息队列解耦订单创建与库存扣减,提升系统吞吐量
- 智能推荐引擎:基于用户行为数据构建协同过滤模型,实现个性化菜品推荐
- 微服务化改造:将单体应用拆分为用户服务、订单服务、商品服务等独立模块,提升系统可维护性
该智能餐饮订购系统通过严谨的架构设计和深度的业务逻辑实现,为餐饮企业提供了稳定可靠的数字化运营基础。系统在保证高性能的同时,具备良好的扩展性和可维护性,为后续的功能迭代和技术升级奠定了坚实基础。