基于SSM框架的校园二手商品交易平台 - 源码深度解析

JavaJavaScriptHTMLCSSSSM框架MavenMySQL
2026-02-0710 浏览

文章摘要

本项目是一款基于SSM(Spring + Spring MVC + MyBatis)框架构建的校园二手商品交易平台,旨在为高校师生提供一个安全、便捷、高效的闲置物品交易环境。其核心业务价值在于盘活校园内的闲置资源,解决传统线下交易信息不对称、交易流程繁琐、信任度低等痛点。通过标准化的商品发布、搜索、...

在高校校园环境中,二手商品交易具有明显的季节性和周期性特征。每到毕业季、开学季,大量闲置物品需要流转,而传统线下交易方式存在信息不对称、交易效率低、信任度不足等问题。校园二手交易平台应运而生,通过数字化手段解决这些痛点,促进资源循环利用。

系统架构与技术栈

该平台采用经典的SSM(Spring + Spring MVC + MyBatis)三层架构,结合Maven进行项目依赖管理,MySQL作为数据存储方案。前端使用HTML、CSS和JavaScript构建用户界面,确保良好的交互体验。

技术架构层次

  • 表现层:Spring MVC框架处理Web请求,JSP页面渲染视图
  • 业务层:Spring IoC容器管理业务Bean,AOP处理横切关注点
  • 持久层:MyBatis实现数据持久化,SQL映射配置灵活
  • 数据层:MySQL数据库存储业务数据
<!-- Maven依赖配置示例 -->
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.18</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.7</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
</dependencies>

数据库设计亮点

商品表设计优化

商品表(goods)的设计体现了对校园交易场景的深度理解:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品主键',
  `catelog_id` int(11) DEFAULT NULL COMMENT '商品分类,外键',
  `user_id` int(11) DEFAULT NULL COMMENT '用户外键',
  `name` varchar(255) DEFAULT NULL COMMENT '商品名称',
  `price` float(11,2) DEFAULT NULL COMMENT '出售价格',
  `real_price` float(11,2) DEFAULT NULL COMMENT '真实价格',
  `start_time` varchar(255) DEFAULT NULL COMMENT '发布时间',
  `polish_time` varchar(255) DEFAULT NULL COMMENT '擦亮时间,按该时间进行查询,精确到时分秒',
  `end_time` varchar(255) DEFAULT NULL COMMENT '下架时间',
  `describle` text DEFAULT NULL COMMENT '详细信息',
  `status` int(11) DEFAULT 1 COMMENT '状态 上架1 下架0',
  PRIMARY KEY (`id`),
  KEY `catelog_id` (`catelog_id`) USING BTREE,
  KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci

设计亮点分析

  1. 时间字段优化polish_time字段专门用于"擦亮"功能,允许卖家刷新商品显示顺序,提升曝光率
  2. 价格字段设计:同时记录price(出售价)和real_price(原价),方便买家比较折扣力度
  3. 状态管理status字段使用枚举值(0/1)管理商品上下架状态,业务逻辑清晰
  4. 索引策略:对catelog_iduser_id建立BTREE索引,优化分类查询和用户商品管理性能

图片表与评论表的关系设计

CREATE TABLE `image` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '图片主键',
  `goods_id` int(11) NOT NULL COMMENT '商品外键',
  `img_url` text NOT NULL COMMENT '图片链接',
  PRIMARY KEY (`id`),
  KEY `goods_id` (`goods_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci

CREATE TABLE `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '评论主键',
  `user_id` int(11) DEFAULT NULL COMMENT '用户,外键',
  `goods_id` int(11) DEFAULT NULL COMMENT '商品,外键',
  `content` varchar(255) DEFAULT NULL COMMENT '评论内容',
  `create_at` varchar(250) DEFAULT NULL COMMENT '评论时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=129 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci

关系设计优势

  • 一对多关系:一个商品对应多张图片,支持多角度展示
  • 评论系统:建立用户-商品-评论的三元关系,支持交易反馈
  • 文本字段优化:评论内容使用varchar(255),图片链接使用text类型,合理分配存储空间

商品详情页

核心功能实现

管理员权限控制与会话管理

管理员控制器实现了完整的权限验证和会话管理机制:

@Controller
@RequestMapping(value = "/admin")
public class AdminController {

    @Resource
    private AdminService adminService;

    @RequestMapping(value = "", method = RequestMethod.GET)
    public String login(HttpSession session) {
        // 清除session
        session.invalidate();
        return "/admin/login";
    }

    @RequestMapping(value = "/index", method = RequestMethod.POST)
    public String index(HttpServletRequest request, Admin admins) {
        Admin myadmin = adminService.findAdmin(admins.getPhone(), admins.getPassword());
        if (myadmin != null) {
            request.getSession().setAttribute("admin", myadmin);
            return "/admin/index";
        }
        return "/admin/login";
    }

    @RequestMapping(value = "/indexs")
    public String indexs(HttpServletRequest request) {
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        if (admin != null) {
            Integer id = admin.getId();
            Admin myadmin = adminService.findAdminById(id);
            request.getSession().setAttribute("admin", myadmin);
            return "/admin/index";
        }
        return "/admin/login";
    }
}

安全特性

  • 会话验证:每次访问管理界面都重新验证管理员身份
  • 会话清理:登录前清除现有会话,防止会话固定攻击
  • 权限控制:通过Session存储管理员信息,实现页面级权限控制

管理员登录

商品发布与管理系统

商品服务层实现了完整的CRUD操作和业务逻辑:

@Service("goodsService")
public class GoodsServiceImpl implements GoodsService {
    
    @Resource
    private GoodsMapper goodsMapper;
    
    @Override
    public int addGoods(Goods goods) {
        // 设置发布时间和初始状态
        goods.setStart_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        goods.setPolish_time(goods.getStart_time());
        goods.setStatus(1); // 上架状态
        
        return goodsMapper.insert(goods);
    }
    
    @Override
    public List<Goods> getGoodsBySearch(String search) {
        // 实现商品搜索功能
        return goodsMapper.selectBySearch(search);
    }
    
    @Override
    public int updateGoodsById(Goods goods) {
        // 更新商品信息,同时更新擦亮时间
        goods.setPolish_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return goodsMapper.updateByPrimaryKey(goods);
    }
}

业务逻辑亮点

  • 自动时间戳:发布商品时自动设置时间字段
  • 状态管理:统一的商品状态流转控制
  • 搜索优化:支持关键词搜索,提升用户体验

发布闲置物品

关注功能与用户交互

关注表设计支持用户间的商品关注机制:

@Service("focusService")
public class FocusServiceImpl implements FocusService {
    
    @Resource
    private FocusMapper focusMapper;
    
    @Override
    public Focus getFocusByUserIdAndGoodsId(Integer userId, Integer goodsId) {
        return focusMapper.selectByUserIdAndGoodsId(userId, goodsId);
    }
    
    @Override
    public int addFocus(Integer userId, Integer goodsId) {
        Focus focus = new Focus();
        focus.setUser_id(userId);
        focus.setGoods_id(goodsId);
        
        // 检查是否已关注
        if (getFocusByUserIdAndGoodsId(userId, goodsId) != null) {
            return -1; // 已关注
        }
        
        return focusMapper.insert(focus);
    }
    
    @Override
    public List<Goods> getFocusGoodsByUserId(Integer userId) {
        return focusMapper.selectFocusGoodsByUserId(userId);
    }
}

交互设计优势

  • 防重复关注:业务层验证防止重复关注
  • 关联查询:高效查询用户关注的所有商品
  • 用户体验:支持商品收藏,提升用户粘性

关注列表

订单管理与交易流程

订单服务处理完整的交易生命周期:

@Controller
@RequestMapping("/orders")
public class OrdersController {
    
    @Resource
    private OrdersService ordersService;
    
    @Resource
    private GoodsService goodsService;
    
    @RequestMapping(value = "/addOrders", method = RequestMethod.POST)
    @ResponseBody
    public String addOrders(HttpServletRequest request, Orders orders) {
        User user = (User) request.getSession().getAttribute("cur_user");
        
        if (user == null) {
            return "未登录";
        }
        
        // 设置订单基本信息
        orders.setUser_id(user.getId());
        orders.setOrder_date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        orders.setStatus(0); // 待支付状态
        
        // 验证商品状态
        Goods goods = goodsService.getGoodsById(orders.getGoods_id());
        if (goods == null || goods.getStatus() != 1) {
            return "商品已下架";
        }
        
        int result = ordersService.addOrders(orders);
        if (result > 0) {
            // 更新商品状态为已售出
            goods.setStatus(0);
            goodsService.updateGoodsById(goods);
            
            return "success";
        }
        
        return "订单创建失败";
    }
}

交易安全机制

  • 状态验证:创建订单前验证商品可用状态
  • 事务一致性:确保订单创建与商品状态更新的原子性
  • 会话验证:基于用户会话的权限控制

订单管理

实体模型设计

管理员实体与业务逻辑

public class Admin {
    private Integer id;
    private String username;
    private Long phone;
    private String password;
    private String userRole;
    
    // 构造方法、getter和setter
    public Admin() {}
    
    public Admin(String username, Long phone, String password, String userRole) {
        this.username = username;
        this.phone = phone;
        this.password = password;
        this.userRole = userRole;
    }
    
    // getter和setter方法
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    
    public Long getPhone() { return phone; }
    public void setPhone(Long phone) { this.phone = phone; }
    
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    
    public String getUserRole() { return userRole; }
    public void setUserRole(String userRole) { this.userRole = userRole; }
}

商品实体与数据映射

public class Goods {
    private Integer id;
    private Integer catelog_id;
    private Integer user_id;
    private String name;
    private Float price;
    private Float real_price;
    private String start_time;
    private String polish_time;
    private String end_time;
    private String describle;
    private Integer status;
    
    // 关联对象
    private User user;
    private Catelog catelog;
    private List<Image> images;
    
    // 业务方法
    public boolean isOnSale() {
        return status != null && status == 1;
    }
    
    public boolean canBePolished() {
        // 判断商品是否可以擦亮(如24小时内只能擦亮一次)
        return isOnSale(); // 简化实现
    }
    
    // 标准getter和setter方法
    // ...
}

功能展望与优化

1. 引入Redis缓存提升性能

现状分析:当前系统频繁查询商品列表、分类信息等热点数据,直接访问数据库造成性能瓶颈。

优化方案

@Service
public class GoodsServiceWithCache {
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String GOODS_LIST_KEY = "goods:list:";
    private static final long CACHE_EXPIRE = 3600; // 1小时
    
    public List<Goods> getGoodsByCatelogWithCache(Integer catelogId) {
        String cacheKey = GOODS_LIST_KEY + catelogId;
        
        // 先查缓存
        List<Goods> goodsList = (List<Goods>) redisTemplate.opsForValue().get(cacheKey);
        if (goodsList != null) {
            return goodsList;
        }
        
        // 缓存未命中,查询数据库
        goodsList = goodsMapper.selectByCatelogId(catelogId);
        
        // 写入缓存
        redisTemplate.opsForValue().set(cacheKey, goodsList, CACHE_EXPIRE, TimeUnit.SECONDS);
        
        return goodsList;
    }
}

2. 消息队列实现异步处理

应用场景:图片处理、消息通知、数据统计等耗时操作可以异步化。

技术选型:RabbitMQ或Redis Streams

@Component
public class MessageQueueService {
    
    @Resource
    private AmqpTemplate rabbitTemplate;
    
    // 发送商品发布消息
    public void sendGoodsPublishMessage(Goods goods) {
        rabbitTemplate.convertAndSend("goods.exchange", "goods.publish", goods);
    }
    
    // 消费者处理图片压缩
    @RabbitListener(queues = "image.process.queue")
    public void processGoodsImage(Goods goods) {
        // 异步处理商品图片压缩和水印添加
        imageService.compressAndWatermark(goods.getImages());
    }
}

3. 微服务架构改造

架构目标:将单体应用拆分为用户服务、商品服务、订单服务、支付服务等微服务。

技术栈:Spring Cloud + Docker + Kubernetes

# 商品服务配置示例
spring:
  application:
    name: goods-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: localhost:8080

# API网关路由配置
spring:
  cloud:
    gateway:
      routes:
        - id: goods-service
          uri: lb://goods-service
          predicates:
            - Path=/api/goods/**

4. 移动端适配与PWA支持

技术方案:开发React Native移动应用或实现PWA(渐进式Web应用)

// 商品浏览组件示例
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, Image } from 'react-native';

const GoodsList = ({ categoryId }) => {
    const [goods, setGoods] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        fetchGoods();
    }, [categoryId]);

    const fetchGoods = async () => {
        try {
            const response = await fetch(`/api/goods/category/${categoryId}`);
            const data = await response.json();
            setGoods(data);
        } catch (error) {
            console.error('获取商品失败:', error);
        } finally {
            setLoading(false);
        }
    };

    return (
        <FlatList
            data={goods}
            keyExtractor={item => item.id.toString()}
            renderItem={({ item }) => (
                <View style={styles.goodsItem}>
                    <Image source={{ uri: item.images[0] }} style={styles.goodsImage} />
                    <Text style={styles.goodsName}>{item.name}</Text>
                    <Text style={styles.goodsPrice}>¥{item.price}</Text>
                </View>
            )}
        />
    );
};

5. 智能推荐与数据分析

功能规划:基于用户行为数据实现个性化商品推荐。

@Service
public class RecommendationService {
    
    @Resource
    private UserBehaviorMapper behaviorMapper;
    
    public List<Goods> getPersonalizedRecommendations(Integer userId) {
        // 基于协同过滤算法
        List<Integer> similarUsers = findSimilarUsers(userId);
        List<Goods> recommendations = new ArrayList<>();
        
        for (Integer similarUserId : similarUsers) {
            List<Goods> goods = goodsService.getGoodsByUserId(similarUserId);
            recommendations.addAll(goods);
        }
        
        return recommendations.stream()
                .distinct()
                .limit(10)
                .collect(Collectors.toList());
    }
    
    private List<Integer> findSimilarUsers(Integer userId) {
        // 实现用户相似度计算
        return behaviorMapper.findSimilarUsers(userId);
    }
}

总结

该校园二手交易平台通过SSM框架实现了稳定可靠的三层架构,数据库设计合理考虑了校园交易场景的特殊需求。商品管理、用户交互、订单处理等核心功能完善,代码结构清晰可维护。通过引入缓存、消息队列、微服务等现代技术

本文关键词
SSM框架校园二手交易平台MyBatis优化数据库设计Spring MVC

上下篇

上一篇
没有更多文章
下一篇
没有更多文章