在传统水果批发行业中,信息不对称、交易链条冗长、价格不透明以及订单处理效率低下等问题长期制约着行业发展。针对这些痛点,我们设计并实现了一个基于SSM框架的企业级水果供应链管理平台,通过数字化手段重构水果批发业务流程,为供应商与采购商搭建高效、透明的线上交易渠道。
系统架构与技术栈
该平台采用经典的三层架构设计,前端使用JSP结合JSTL标签库进行页面渲染,配合jQuery实现丰富的用户交互体验。后端基于SSM(Spring+SpringMVC+MyBatis)框架构建,Spring框架作为核心容器负责依赖注入和事务管理,SpringMVC处理Web层请求路由和参数绑定,MyBatis作为持久层框架完成数据访问操作。
技术栈配置如下:
- 后端框架:Spring 4.3 + SpringMVC 4.3 + MyBatis 3.4
- 前端技术:JSP 2.3 + JSTL 1.2 + jQuery 3.2 + Bootstrap 4.0
- 数据库:MySQL 5.7 + Druid连接池
- 服务器:Tomcat 8.5 + Maven 3.5
<!-- Spring核心配置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/fruit_db"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
数据库设计亮点分析
水果商品表(fruit)的精细化设计
fruit表作为核心业务表,其设计充分考虑了水果行业的特殊需求:
CREATE TABLE `fruit` (
`fruitid` varchar(255) NOT NULL COMMENT '水果编号',
`fruitname` varchar(255) DEFAULT NULL COMMENT '水果名称',
`image` varchar(255) DEFAULT NULL COMMENT '图片',
`cateid` varchar(255) DEFAULT NULL COMMENT '分类编号',
`price` varchar(255) DEFAULT NULL COMMENT '价格',
`recommend` varchar(255) DEFAULT NULL COMMENT '是否推荐',
`thestart` varchar(255) DEFAULT NULL COMMENT '开始时间',
`theend` varchar(255) DEFAULT NULL COMMENT '结束时间',
`hits` varchar(255) DEFAULT NULL COMMENT '点击数',
`sellnum` varchar(255) DEFAULT NULL COMMENT '销售数量',
`contents` varchar(6000) DEFAULT NULL COMMENT '内容',
PRIMARY KEY (`fruitid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='水果'
设计亮点分析:
- 扩展性字段设计:
contents字段设置为6000字符长度,充分满足水果商品详情的富文本描述需求,支持产地介绍、营养价值、存储方式等详细信息 - 营销功能集成:通过
recommend字段实现推荐商品功能,hits和sellnum字段为销售分析提供数据支撑 - 时效性控制:
thestart和theend字段有效管理季节性水果的上架周期,避免过季商品展示 - 外键关联优化:
cateid与分类表建立关联,支持灵活的商品分类管理
配货点表(peihuo)的区域化部署设计
CREATE TABLE `peihuo` (
`peihuoid` varchar(255) NOT NULL COMMENT '配货点编号',
`peihuoname` varchar(255) DEFAULT NULL COMMENT '配货点名称',
`cityid` varchar(255) DEFAULT NULL COMMENT '城市编号',
`address` varchar(255) DEFAULT NULL COMMENT '地址',
`contact` varchar(255) DEFAULT NULL COMMENT '联系方式',
`memo` varchar(255) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`peihuoid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='配货点'
区域性配送优化:通过cityid与城市表关联,实现按区域智能分配配货点,大幅降低物流成本。配合地理信息系统可进一步优化配送路线规划。
话题讨论表(topic)的社交化设计
CREATE TABLE `topic` (
`topicid` varchar(255) NOT NULL COMMENT '话题编号',
`usersid` varchar(255) DEFAULT NULL COMMENT '用户编号',
`fruitid` varchar(255) DEFAULT NULL COMMENT '水果编号',
`num` varchar(255) DEFAULT NULL COMMENT '数量',
`contents` varchar(6000) DEFAULT NULL COMMENT '内容',
`addtime` varchar(255) DEFAULT NULL COMMENT '添加时间',
PRIMARY KEY (`topicid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='话题'
社区化运营支持:该表设计支持用户对特定水果商品进行讨论和评价,contents字段的大容量设计满足详细的用户反馈需求,为平台建立用户社区提供数据基础。

核心功能实现详解
商品管理模块
商品管理采用MVC模式实现,Controller层处理前端请求,Service层封装业务逻辑,DAO层负责数据持久化。
商品添加功能实现:
@Controller
@RequestMapping("/fruit")
public class FruitController {
@Autowired
private FruitService fruitService;
@RequestMapping(value = "/insert", method = RequestMethod.POST)
public String insert(Fruit fruit, HttpServletRequest request) {
fruit.setFruitid("F" + VeDate.getStringId());
fruit.setAddtime(VeDate.getNow());
fruit.setHits("0");
fruit.setSellnum("0");
this.fruitService.insertFruit(fruit);
request.setAttribute("message", "添加水果成功");
return "redirect:/fruit/list";
}
@RequestMapping("/list")
public String list(HttpServletRequest request) {
List<Fruit> fruitList = this.fruitService.getAllFruit();
request.setAttribute("fruitList", fruitList);
return "admin/fruit/list";
}
}
@Service
public class FruitService {
@Autowired
private FruitDAO fruitDAO;
public void insertFruit(Fruit fruit) {
try {
this.fruitDAO.insertFruit(fruit);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("添加水果失败");
}
}
public List<Fruit> getAllFruit() {
return this.fruitDAO.findAll();
}
}
MyBatis映射文件配置:
<!-- FruitMapper.xml -->
<mapper namespace="com.dao.FruitDAO">
<insert id="insertFruit" parameterType="com.entity.Fruit">
INSERT INTO fruit(fruitid, fruitname, image, cateid, price,
recommend, thestart, theend, hits, sellnum, contents)
VALUES(#{fruitid}, #{fruitname}, #{image}, #{cateid}, #{price},
#{recommend}, #{thestart}, #{theend}, #{hits}, #{sellnum}, #{contents})
</insert>
<select id="findAll" resultType="com.entity.Fruit">
SELECT * FROM fruit ORDER BY addtime DESC
</select>
<select id="findByCate" parameterType="String" resultType="com.entity.Fruit">
SELECT * FROM fruit WHERE cateid = #{cateid} AND recommend = '是'
</select>
</mapper>

订单处理流程
订单处理采用事务管理确保数据一致性,Spring的声明式事务管理保证订单创建的原子性。
@Service
@Transactional
public class OrdersService {
@Autowired
private OrdersDAO ordersDAO;
@Autowired
private FruitDAO fruitDAO;
public void createOrder(Orders orders, List<Cart> cartList) {
// 1. 创建订单主记录
orders.setOrdersid("O" + VeDate.getStringId());
orders.setAddtime(VeDate.getNow());
orders.setStatus("待付款");
this.ordersDAO.insertOrders(orders);
// 2. 处理购物车商品并更新库存
for (Cart cart : cartList) {
OrderDetails details = new OrderDetails();
details.setDetailsid("D" + VeDate.getStringId());
details.setOrdersid(orders.getOrdersid());
details.setFruitid(cart.getFruitid());
details.setNum(cart.getNum());
details.setPrice(cart.getPrice());
// 插入订单明细
this.ordersDAO.insertOrderDetails(details);
// 更新水果库存
Fruit fruit = this.fruitDAO.findById(cart.getFruitid());
int newSellnum = Integer.parseInt(fruit.getSellnum()) + Integer.parseInt(cart.getNum());
fruit.setSellnum(String.valueOf(newSellnum));
this.fruitDAO.updateFruit(fruit);
}
}
}
用户权限管理
基于Spring拦截器实现权限控制,确保不同角色用户访问相应功能。
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
// 放行公开资源
if (uri.contains("/login") || uri.contains("/register") ||
uri.contains("/static/") || uri.contains("/index")) {
return true;
}
// 检查管理员权限
if (uri.contains("/admin/")) {
Admin admin = (Admin) request.getSession().getAttribute("admin");
if (admin == null) {
response.sendRedirect(request.getContextPath() + "/admin/login.jsp");
return false;
}
}
// 检查用户权限
if (uri.contains("/user/")) {
Users user = (Users) request.getSession().getAttribute("user");
if (user == null) {
response.sendRedirect(request.getContextPath() + "/user/login.jsp");
return false;
}
}
return true;
}
}

实体模型设计
实体类采用标准的JavaBean规范,通过Getter和Setter方法封装属性,支持Spring的依赖注入。
package com.entity;
import com.util.VeDate;
public class Fruit {
private String fruitid = "F" + VeDate.getStringId();
private String fruitname;
private String image;
private String cateid;
private String price;
private String recommend;
private String thestart;
private String theend;
private String hits;
private String sellnum;
private String contents;
private String addtime;
// Getter和Setter方法
public String getFruitid() {
return fruitid;
}
public void setFruitid(String fruitid) {
this.fruitid = fruitid;
}
public String getFruitname() {
return fruitname;
}
public void setFruitname(String fruitname) {
this.fruitname = fruitname;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getCateid() {
return cateid;
}
public void setCateid(String cateid) {
this.cateid = cateid;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getRecommend() {
return recommend;
}
public void setRecommend(String recommend) {
this.recommend = recommend;
}
public String getThestart() {
return thestart;
}
public void setThestart(String thestart) {
this.thestart = thestart;
}
public String getTheend() {
return theend;
}
public void setTheend(String theend) {
this.theend = theend;
}
public String getHits() {
return hits;
}
public void setHits(String hits) {
this.hits = hits;
}
public String getSellnum() {
return sellnum;
}
public void setSellnum(String sellnum) {
this.sellnum = sellnum;
}
public String getContents() {
return contents;
}
public void setContents(String contents) {
this.contents = contents;
}
public String getAddtime() {
return addtime;
}
public void setAddtime(String addtime) {
this.addtime = addtime;
}
}

功能展望与优化方向
1. 引入Redis缓存提升性能
在当前架构基础上,可以引入Redis作为缓存层,显著提升系统性能:
@Service
public class FruitServiceWithCache {
@Autowired
private RedisTemplate<String, Fruit> redisTemplate;
@Autowired
private FruitDAO fruitDAO;
public Fruit getFruitById(String fruitid) {
String cacheKey = "fruit:" + fruitid;
Fruit fruit = redisTemplate.opsForValue().get(cacheKey);
if (fruit == null) {
fruit = fruitDAO.findById(fruitid);
if (fruit != null) {
redisTemplate.opsForValue().set(cacheKey, fruit, 30, TimeUnit.MINUTES);
}
}
return fruit;
}
}
2. 微服务架构改造
将单体应用拆分为微服务架构:
- 用户服务:处理用户注册、登录、权限管理
- 商品服务:管理水果商品信息、库存、分类
- 订单服务:处理订单创建、支付、状态跟踪
- 配送服务:管理配货点、物流跟踪
3. 移动端适配与PWA支持
开发响应式前端界面,支持PWA(渐进式Web应用)技术,实现类似原生应用的体验:
// 注册Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('SW注册成功: ', registration);
});
}
4. 智能推荐系统集成
基于用户行为数据构建推荐算法:
- 协同过滤推荐相似用户喜欢的水果
- 基于内容的推荐相似特征商品
- 实时推荐根据当前会话行为推荐
5. 大数据分析平台
构建数据分析模块,为供应商提供销售洞察:
- 销售趋势分析
- 地域销售分布
- 用户购买行为分析
- 库存预测模型

该水果供应链管理平台通过SSM框架的稳定性和扩展性,为传统水果批发行业提供了完整的数字化解决方案。系统架构清晰,代码规范,具备良好的可维护性和扩展性。未来通过引入缓存、微服务、移动端适配等优化措施,可以进一步提升系统性能和用户体验,为水果行业的数字化转型提供强有力的技术支撑。