在当前的电商领域,个性化推荐已成为提升用户体验和转化率的关键技术。特别是对于零食这类快消品电商平台,用户往往面临海量商品选择困难的问题。本文介绍的智能零食推荐引擎正是基于SSM框架与协同过滤算法构建的完整解决方案。
系统架构与技术栈
该平台采用经典的三层架构设计,前端使用HTML、CSS和JavaScript构建响应式用户界面,后端基于Spring+SpringMVC+MyBatis框架组合,数据存储采用MySQL关系型数据库。整个项目使用Maven进行依赖管理和构建。
技术栈组成:
- 表现层:SpringMVC负责请求分发和视图解析
- 业务层:Spring框架管理业务逻辑和事务控制
- 持久层:MyBatis实现数据访问对象映射
- 推荐引擎:基于用户的协同过滤算法
- 前端技术:传统三件套结合AJAX异步交互
数据库设计亮点分析
商品表设计优化
CREATE TABLE `item` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`name` varchar(255) DEFAULT NULL COMMENT '名字',
`price` varchar(255) DEFAULT NULL COMMENT '价格',
`scNum` int(11) DEFAULT NULL COMMENT '收藏数',
`gmNum` int(11) DEFAULT NULL COMMENT '购买数',
`url1` varchar(255) DEFAULT NULL COMMENT '图片URL1',
`url2` varchar(255) DEFAULT NULL COMMENT '图片URL2',
`url3` varchar(255) DEFAULT NULL COMMENT '图片URL3',
`url4` varchar(255) DEFAULT NULL COMMENT '图片URL4',
`url5` varchar(255) DEFAULT NULL COMMENT '图片URL5',
`ms` text DEFAULT NULL COMMENT '描述',
`pam1` varchar(255) DEFAULT NULL COMMENT '参数1',
`pam2` varchar(255) DEFAULT NULL COMMENT '参数2',
`pam3` varchar(255) DEFAULT NULL COMMENT '参数3',
`val3` varchar(255) DEFAULT NULL COMMENT '值3',
`val2` varchar(255) DEFAULT NULL COMMENT '值2',
`val1` varchar(255) DEFAULT NULL COMMENT '值1',
`type` int(11) DEFAULT NULL COMMENT '类型',
`zk` int(10) DEFAULT NULL COMMENT '折扣',
`category_id_one` int(11) DEFAULT NULL COMMENT '类别id',
`category_id_two` int(11) DEFAULT NULL COMMENT '类别2级',
`isDelete` int(2) DEFAULT NULL COMMENT '0否 1是',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'
商品表设计体现了电商系统的核心需求。采用多图片URL字段(url1-url5)支持商品详情页的多图展示,text类型的ms字段容纳详细商品描述。scNum(收藏数)和gmNum(购买数)为推荐算法提供重要权重依据。两级分类设计(category_id_one、category_id_two)支持灵活的品类管理。
订单详情表设计
CREATE TABLE `order_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`item_id` int(255) DEFAULT NULL COMMENT '商品ID',
`order_id` int(11) DEFAULT NULL COMMENT '订单ID',
`status` int(11) DEFAULT NULL COMMENT '0.未退货 1已退货',
`num` int(11) DEFAULT NULL COMMENT '数量',
`total` varchar(255) DEFAULT NULL COMMENT '总价',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单详情表'
订单详情表采用与主订单表分离的设计,支持一个订单包含多个商品。status字段实现退货状态跟踪,num和total字段分别记录购买数量和金额,为销售数据分析提供基础。

核心功能实现
基础控制器设计
系统的基础控制器提供了统一的响应处理和工具方法:
package com.neusoft.base;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
public class BaseController {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
protected final static String DATE_FORMATE = "yyyy-MM-dd";
public String responseResult(Object obj) {
String jsonObj = null;
if (obj != null) {
logger.info("后端返回对象:{}", obj);
jsonObj = JSONObject.toJSONString(obj);
logger.info("后端返回数据:" + jsonObj);
}
logger.info("输出结果:{}", jsonObj);
return jsonObj;
}
public boolean isEmpty(String str) {
return (null == str) || (str.trim().length() <= 0);
}
public boolean isEmpty(Character cha) {
return (null == cha) || cha.equals(' ');
}
public boolean isEmpty(Object obj) {
return (null == obj);
}
public Map<String,Object> getMap(){
return new HashMap<String,Object>();
}
}
该基类封装了JSON响应转换、日志记录和空值判断等通用功能,确保所有控制器的一致性。
协同过滤推荐算法实现
推荐模块采用基于用户的协同过滤算法,核心逻辑包括相似度计算和推荐生成:
public class CollaborativeFiltering {
// 计算用户相似度(皮尔逊相关系数)
public double calculateSimilarity(Map<Integer, Double> user1,
Map<Integer, Double> user2) {
// 找出共同评价的商品
List<Integer> commonItems = new ArrayList<>();
for (Integer itemId : user1.keySet()) {
if (user2.containsKey(itemId)) {
commonItems.add(itemId);
}
}
if (commonItems.size() == 0) return 0;
// 计算相关系数
double sum1 = 0, sum2 = 0, sum1Sq = 0, sum2Sq = 0, pSum = 0;
for (Integer itemId : commonItems) {
double rating1 = user1.get(itemId);
double rating2 = user2.get(itemId);
sum1 += rating1;
sum2 += rating2;
sum1Sq += Math.pow(rating1, 2);
sum2Sq += Math.pow(rating2, 2);
pSum += rating1 * rating2;
}
double num = pSum - (sum1 * sum2 / commonItems.size());
double den = Math.sqrt((sum1Sq - Math.pow(sum1, 2) / commonItems.size()) *
(sum2Sq - Math.pow(sum2, 2) / commonItems.size()));
return den == 0 ? 0 : num / den;
}
// 生成推荐列表
public List<Recommendation> generateRecommendations(int userId,
int maxRecommendations) {
Map<Integer, Double> totalScores = new HashMap<>();
Map<Integer, Double> similaritySums = new HashMap<>();
// 遍历所有用户计算相似度
for (User otherUser : getAllUsers()) {
if (otherUser.getId() == userId) continue;
double similarity = calculateSimilarity(
getUserRatings(userId), getUserRatings(otherUser.getId()));
if (similarity <= 0) continue;
// 为当前用户未评价的商品加权评分
for (Map.Entry<Integer, Double> rating :
getUserRatings(otherUser.getId()).entrySet()) {
if (!getUserRatings(userId).containsKey(rating.getKey())) {
totalScores.merge(rating.getKey(),
rating.getValue() * similarity, Double::sum);
similaritySums.merge(rating.getKey(), similarity, Double::sum);
}
}
}
// 计算加权平均并排序
List<Recommendation> recommendations = new ArrayList<>();
for (Integer itemId : totalScores.keySet()) {
double weightedAverage = totalScores.get(itemId) / similaritySums.get(itemId);
recommendations.add(new Recommendation(itemId, weightedAverage));
}
return recommendations.stream()
.sorted(Comparator.comparing(Recommendation::getScore).reversed())
.limit(maxRecommendations)
.collect(Collectors.toList());
}
}

商品管理功能
商品管理模块支持多图上传、分类管理和库存控制:
@Controller
@RequestMapping("/admin/item")
public class ItemAdminController extends BaseController {
@Autowired
private ItemService itemService;
@RequestMapping("/add")
public String addItem(@ModelAttribute Item item,
@RequestParam("files") MultipartFile[] files) {
try {
// 处理图片上传
List<String> imageUrls = new ArrayList<>();
for (MultipartFile file : files) {
if (!file.isEmpty()) {
String fileName = FileUtil.uploadFile(file);
imageUrls.add(fileName);
}
}
// 设置图片URL
if (imageUrls.size() > 0) item.setUrl1(imageUrls.get(0));
if (imageUrls.size() > 1) item.setUrl2(imageUrls.get(1));
// ... 设置其他URL字段
itemService.addItem(item);
return "redirect:/admin/item/list";
} catch (Exception e) {
logger.error("添加商品失败", e);
return "error";
}
}
@RequestMapping("/list")
@ResponseBody
public String getItemList(@RequestParam Map<String, Object> params) {
PageInfo<Item> pageInfo = itemService.getItemList(params);
return responseResult(pageInfo);
}
}

用户购物车实现
购物车模块采用Session和数据库结合的方式保证数据持久性:
@Service
public class CartService {
public void addToCart(Integer userId, Integer itemId, Integer quantity) {
// 检查商品是否存在且库存充足
Item item = itemService.getItemById(itemId);
if (item == null || item.getIsDelete() == 1) {
throw new BusinessException("商品不存在或已下架");
}
// 检查购物车中是否已有该商品
CartItem cartItem = cartMapper.findByUserIdAndItemId(userId, itemId);
if (cartItem != null) {
// 更新数量
cartItem.setNum(cartItem.getNum() + quantity);
cartMapper.updateCartItem(cartItem);
} else {
// 新增购物车项
cartItem = new CartItem();
cartItem.setUserId(userId);
cartItem.setItemId(itemId);
cartItem.setNum(quantity);
cartItem.setAddTime(new Date());
cartMapper.addCartItem(cartItem);
}
}
public List<CartVO> getCartList(Integer userId) {
return cartMapper.getCartListByUserId(userId);
}
}

订单处理流程
订单模块实现完整的下单、支付、发货流程:
@Service
@Transactional
public class OrderService {
public Order createOrder(Integer userId, List<CartItem> cartItems,
String address, String phone) {
Order order = new Order();
order.setUserId(userId);
order.setOrderNo(generateOrderNo());
order.setStatus(0); // 待支付
order.setTotal(calculateTotal(cartItems));
order.setAddress(address);
order.setPhone(phone);
order.setCreateTime(new Date());
orderMapper.addOrder(order);
// 创建订单详情
for (CartItem cartItem : cartItems) {
OrderDetail detail = new OrderDetail();
detail.setOrderId(order.getId());
detail.setItemId(cartItem.getItemId());
detail.setNum(cartItem.getNum());
detail.setTotal(calculateItemTotal(cartItem));
orderDetailMapper.addOrderDetail(detail);
// 更新商品销量
itemMapper.increaseSales(cartItem.getItemId(), cartItem.getNum());
}
return order;
}
private String generateOrderNo() {
return "SN" + System.currentTimeMillis() +
String.format("%04d", new Random().nextInt(10000));
}
}

实体模型设计
系统采用标准的JavaBean实体类设计,与数据库表结构一一对应:
public class Item implements Serializable {
private Integer id;
private String name;
private String price;
private Integer scNum;
private Integer gmNum;
private String url1;
private String url2;
private String url3;
private String url4;
private String url5;
private String ms;
private String pam1;
private String pam2;
private String pam3;
private String val1;
private String val2;
private String val3;
private Integer type;
private Integer zk;
private Integer categoryIdOne;
private Integer categoryIdTwo;
private Integer isDelete;
// getter和setter方法
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
// ... 其他getter/setter
}
功能展望与优化方向
1. 引入Redis缓存提升性能
当前系统在推荐计算和高频查询方面存在性能瓶颈。可引入Redis缓存用户行为数据、热门商品和推荐结果:
@Service
public class RecommendationServiceWithCache {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String RECOMMENDATION_KEY = "user:recommendations:";
private static final long CACHE_EXPIRE = 3600; // 1小时
public List<Recommendation> getRecommendationsWithCache(Integer userId) {
String key = RECOMMENDATION_KEY + userId;
List<Recommendation> recommendations =
(List<Recommendation>) redisTemplate.opsForValue().get(key);
if (recommendations == null) {
recommendations = generateRecommendations(userId);
redisTemplate.opsForValue().set(key, recommendations,
CACHE_EXPIRE, TimeUnit.SECONDS);
}
return recommendations;
}
}
2. 微服务架构改造
将单体应用拆分为用户服务、商品服务、订单服务、推荐服务等微服务,提升系统可扩展性和维护性。
3. 实时推荐引擎
引入Apache Flink或Spark Streaming实现实时推荐,基于用户实时行为动态调整推荐结果。
4. 移动端适配
开发React Native或Flutter移动应用,提供更好的移动购物体验。
5. 智能搜索优化
集成Elasticsearch实现商品智能搜索,支持拼音搜索、同义词扩展和搜索建议。
总结
该智能零食推荐引擎成功实现了基于SSM框架的电商平台核心功能,特别是协同过滤推荐算法的集成有效解决了商品信息过载问题。系统架构清晰,代码规范,具备良好的扩展性。通过后续的性能优化和功能扩展,可以进一步提升系统的商业价值和用户体验。
系统的数据库设计合理,特别是商品表和订单表的结构充分考虑了电商业务的实际需求。推荐算法模块的实现展示了数据挖掘技术在电商领域的实际应用价值。整体而言,这是一个技术实现完整、业务逻辑清晰的电商推荐系统典范。