基于SSM的在线车辆销售交易平台 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQL
2026-02-0810 浏览

文章摘要

本项目是一个基于SSM(Spring+Spring MVC+MyBatis)框架构建的在线车辆销售交易平台,旨在为汽车经销商与个人买家提供一个高效、安全、一站式的数字化交易环境。其核心业务价值在于彻底改变了传统线下购车流程中信息不透明、地域限制强、交易周期长的痛点。通过将车辆展示、信息查询、在线沟通...

随着汽车消费市场的数字化转型加速,传统线下购车模式面临信息不对称、交易效率低等挑战。本文介绍的智能汽车交易平台基于SSM框架构建,通过整合车辆展示、在线交易、订单管理等核心功能,为汽车经销商和消费者提供高效的数字化交易解决方案。

系统架构与技术栈

平台采用经典的三层架构设计,技术栈选择兼顾成熟度与性能要求:

表现层:JSP+HTML+CSS+JavaScript实现响应式前端界面 控制层:Spring MVC框架处理HTTP请求和响应 业务层:Spring IoC容器管理Service组件和事务控制 持久层:MyBatis实现数据访问对象(DAO)与SQL映射

<!-- 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>

数据库设计亮点分析

订单表设计:支持复杂交易流程

CREATE TABLE `ordermsg` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `ddno` varchar(255) DEFAULT NULL COMMENT '订单编号',
  `memberid` varchar(255) DEFAULT NULL COMMENT '会员ID',
  `productid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `num` int(11) DEFAULT NULL COMMENT '商品数量',
  `total` double(255,2) DEFAULT NULL COMMENT '订单总金额',
  `fkstatus` varchar(255) DEFAULT NULL COMMENT '付款状态',
  `shstatus` varchar(11) DEFAULT NULL COMMENT '发货状态',
  `addr` varchar(255) DEFAULT NULL COMMENT '收货地址',
  `savetime` varchar(255) DEFAULT NULL COMMENT '下单时间',
  `delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
  `shfs` varchar(255) DEFAULT NULL COMMENT '送货方式',
  `zffs` varchar(255) DEFAULT NULL COMMENT '支付方式',
  `saver` varchar(255) DEFAULT NULL COMMENT '操作人',
  `isdd` varchar(255) DEFAULT NULL COMMENT '是否订单',
  `fid` varchar(255) DEFAULT NULL COMMENT '父级ID',
  `goodsid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `goodstype` varchar(255) DEFAULT NULL COMMENT '商品类型',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单表'

设计亮点分析

  1. 状态字段精细化:通过fkstatus(付款状态)、shstatus(发货状态)、delstatus(删除状态)等多状态字段,完整跟踪订单生命周期
  2. 业务扩展性isdd字段区分订单类型,fid支持父子订单结构,为后续团购、拼单等业务场景预留扩展空间
  3. 索引优化:主键ID自增设计提升写入性能,建议对ddno(订单编号)、memberid(会员ID)建立复合索引优化查询

商品表设计:支持多级分类管理

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `productno` varchar(255) DEFAULT NULL COMMENT '商品编号',
  `productname` varchar(255) DEFAULT NULL COMMENT '商品名称',
  `filename` varchar(255) DEFAULT NULL COMMENT '图片名称',
  `price` decimal(10,2) DEFAULT NULL COMMENT '现价',
  `tprice` decimal(10,2) DEFAULT NULL COMMENT '原价',
  `fid` varchar(255) DEFAULT NULL COMMENT '一级分类ID',
  `sid` varchar(255) DEFAULT NULL COMMENT '二级分类ID',
  `content` text DEFAULT NULL COMMENT '商品描述',
  `delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
  `issj` varchar(255) DEFAULT NULL COMMENT '是否上架',
  `istj` varchar(255) DEFAULT NULL COMMENT '是否推荐',
  `saver` varchar(255) DEFAULT NULL COMMENT '添加人',
  `productid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `leibie` varchar(255) DEFAULT NULL COMMENT '类别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=137 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'

设计优化建议

  1. 价格字段精度decimal(10,2)类型确保金额计算精度,避免浮点数误差
  2. 分类索引策略:对fidsid建立索引,结合issjistj状态字段实现高效的商品筛选
  3. 文本字段优化content字段使用TEXT类型存储详细描述,建议单独分表或使用全文索引提升搜索性能

商品管理界面

核心功能实现深度解析

1. 商品展示与分类检索系统

平台实现多层次商品分类检索,支持按品牌、价格区间、车况等条件精准筛选:

@Controller
@RequestMapping("/product")
public class ProductController {
    
    @Resource
    private ProductDAO productDAO;
    
    @RequestMapping("/search")
    public String searchProducts(
        @RequestParam(value = "keyword", required = false) String keyword,
        @RequestParam(value = "categoryId", required = false) Integer categoryId,
        @RequestParam(value = "minPrice", required = false) Double minPrice,
        @RequestParam(value = "maxPrice", required = false) Double maxPrice,
        HttpServletRequest request) {
        
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotBlank(keyword)) {
            params.put("keyword", "%" + keyword + "%");
        }
        if (categoryId != null && categoryId > 0) {
            params.put("categoryId", categoryId);
        }
        if (minPrice != null) {
            params.put("minPrice", minPrice);
        }
        if (maxPrice != null) {
            params.put("maxPrice", maxPrice);
        }
        
        List<Product> productList = productDAO.findByConditions(params);
        request.setAttribute("productList", productList);
        return "product/list";
    }
}

对应的MyBatis映射文件实现复杂查询逻辑:

<!-- ProductMapper.xml -->
<select id="findByConditions" parameterType="map" resultType="com.entity.Product">
    SELECT * FROM product 
    WHERE delstatus = '0' AND issj = '1'
    <if test="keyword != null and keyword != ''">
        AND (productname LIKE #{keyword} OR content LIKE #{keyword})
    </if>
    <if test="categoryId != null">
        AND (fid = #{categoryId} OR sid = #{categoryId})
    </if>
    <if test="minPrice != null">
        AND price >= #{minPrice}
    </if>
    <if test="maxPrice != null">
        AND price &lt;= #{maxPrice}
    </if>
    ORDER BY 
        <choose>
            <when test="sortField == 'price'">price</when>
            <when test="sortField == 'sales'">sales_count</when>
            <otherwise>id</otherwise>
        </choose>
    <if test="sortOrder == 'desc'">DESC</if>
    LIMIT #{start}, #{pageSize}
</select>

商品详情页面

2. 购物车与订单生成机制

购物车服务采用Session与数据库结合的方式,确保用户数据的持久化:

@Service
public class CartService {
    
    @Resource
    private ProductDAO productDAO;
    @Resource
    private OrderMsgDAO orderMsgDAO;
    
    public void addToCart(HttpServletRequest request, Integer productId, Integer quantity) {
        HttpSession session = request.getSession();
        Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("cart");
        
        if (cart == null) {
            cart = new HashMap<>();
            session.setAttribute("cart", cart);
        }
        
        Product product = productDAO.findById(productId);
        if (product != null && "1".equals(product.getIssj())) {
            CartItem item = cart.get(productId);
            if (item == null) {
                item = new CartItem(product, quantity);
                cart.put(productId, item);
            } else {
                item.setQuantity(item.getQuantity() + quantity);
            }
        }
    }
    
    @Transactional
    public String createOrder(HttpServletRequest request, String address, String payMethod) {
        HttpSession session = request.getSession();
        Member member = (Member) session.getAttribute("sessionmember");
        Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("cart");
        
        if (cart == null || cart.isEmpty()) {
            return "购物车为空";
        }
        
        OrderMsg order = new OrderMsg();
        order.setDdno(generateOrderNo());
        order.setMemberid(member.getId().toString());
        order.setSavetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        order.setFkstatus("待付款");
        order.setShstatus("待发货");
        order.setAddr(address);
        order.setZffs(payMethod);
        
        double total = 0;
        for (CartItem item : cart.values()) {
            total += item.getProduct().getPrice() * item.getQuantity();
        }
        order.setTotal(total);
        
        orderMsgDAO.save(order);
        session.removeAttribute("cart");
        
        return "订单创建成功,订单号:" + order.getDdno();
    }
    
    private String generateOrderNo() {
        return "DD" + System.currentTimeMillis() + (int)(Math.random() * 1000);
    }
}

购物车页面

3. 后台管理系统实现

后台管理控制器采用基于注解的权限控制和数据验证:

@Controller
@RequestMapping("/admin")
public class AdminProductController extends BaseAdminController {
    
    @Resource
    private ProductDAO productDAO;
    @Resource
    private CategoryDAO categoryDAO;
    
    @RequestMapping("/product/list")
    public String productList(
        @RequestParam(value = "page", defaultValue = "1") Integer page,
        @RequestParam(value = "size", defaultValue = "10") Integer size,
        HttpServletRequest request) {
        
        // 权限验证
        if (!hasAdminRole(request)) {
            return "redirect:/admin/login";
        }
        
        int start = (page - 1) * size;
        List<Product> products = productDAO.findWithPage(start, size);
        int total = productDAO.getTotalCount();
        int totalPages = (int) Math.ceil((double) total / size);
        
        request.setAttribute("products", products);
        request.setAttribute("currentPage", page);
        request.setAttribute("totalPages", totalPages);
        request.setAttribute("categories", categoryDAO.findAll());
        
        return "admin/product_list";
    }
    
    @RequestMapping(value = "/product/save", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> saveProduct(
        @Valid @ModelAttribute Product product,
        BindingResult result,
        @RequestParam("imageFile") MultipartFile imageFile) {
        
        Map<String, Object> response = new HashMap<>();
        
        if (result.hasErrors()) {
            response.put("success", false);
            response.put("message", "数据验证失败");
            return response;
        }
        
        try {
            // 处理图片上传
            if (!imageFile.isEmpty()) {
                String filename = saveUploadedFile(imageFile);
                product.setFilename(filename);
            }
            
            product.setSaver(getCurrentAdmin().getUsername());
            product.setDelstatus("0");
            
            if (product.getId() == null) {
                productDAO.save(product);
            } else {
                productDAO.update(product);
            }
            
            response.put("success", true);
            response.put("message", "保存成功");
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "保存失败:" + e.getMessage());
        }
        
        return response;
    }
}

订单管理后台

4. 用户地址管理系统

地址管理支持多地址维护和默认地址设置:

@Service
public class AddressService {
    
    @Resource
    private AddressDAO addressDAO;
    
    public List<Address> getUserAddresses(Integer memberId) {
        return addressDAO.findByMemberId(memberId);
    }
    
    @Transactional
    public void setDefaultAddress(Integer addressId, Integer memberId) {
        // 取消当前所有默认地址
        addressDAO.cancelAllDefault(memberId);
        // 设置新的默认地址
        addressDAO.setDefault(addressId);
    }
    
    public Address getDefaultAddress(Integer memberId) {
        return addressDAO.findDefaultByMemberId(memberId);
    }
}

对应的DAO实现包含复杂的SQL逻辑:

<!-- AddressMapper.xml -->
<update id="cancelAllDefault" parameterType="int">
    UPDATE address SET ismr = '0' 
    WHERE memberid = #{memberId} AND delstatus = '0'
</update>

<update id="setDefault" parameterType="int">
    UPDATE address SET ismr = '1' 
    WHERE id = #{addressId} AND delstatus = '0'
</update>

<select id="findDefaultByMemberId" parameterType="int" resultType="com.entity.Address">
    SELECT * FROM address 
    WHERE memberid = #{memberId} AND ismr = '1' AND delstatus = '0' 
    LIMIT 1
</select>

地址管理界面

实体模型设计

系统采用标准的JavaBean实体类设计,与数据库表结构严格对应:

package com.entity;

import java.math.BigDecimal;

public class Product {
    private Integer id;
    private String productno;
    private String productname;
    private String filename;
    private BigDecimal price;
    private BigDecimal tprice;
    private String fid;
    private String sid;
    private String content;
    private String delstatus;
    private String issj;
    private String istj;
    private String saver;
    private String productid;
    private String leibie;
    
    // Getter和Setter方法
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    
    public String getProductno() { return productno; }
    public void setProductno(String productno) { this.productno = productno; }
    
    public BigDecimal getPrice() { return price; }
    public void setPrice(BigDecimal price) { this.price = price; }
    
    // 其他getter/setter方法...
    
    @Override
    public String toString() {
        return "Product [id=" + id + ", productname=" + productname + 
               ", price=" + price + ", issj=" + issj + "]";
    }
}

订单实体类包含复杂的业务逻辑字段:

public class OrderMsg {
    private Integer id;
    private String ddno;
    private String memberid;
    private String productid;
    private Integer num;
    private Double total;
    private String fkstatus;
    private String shstatus;
    private String addr;
    private String savetime;
    private String delstatus;
    private String shfs;
    private String zffs;
    private String saver;
    private String isdd;
    private String fid;
    private String goodsid;
    private String goodstype;
    private String remark;
    
    // 枚举类型定义订单状态
    public enum PayStatus {
        PENDING("待付款"), PAID("已付款"), REFUNDED("已退款");
        
        private String description;
        PayStatus(String desc) { this.description = desc; }
        public String getDescription() { return description; }
    }
    
    public enum ShipStatus {
        PENDING("待发货"), SHIPPED("已发货"), DELIVERED("已收货");
        
        private String description;
        ShipStatus(String desc) { this.description = desc; }
        public String getDescription() { return description; }
    }
    
    // Getter和Setter方法...
}

功能展望与优化方向

1. 引入Redis缓存提升性能

现状分析:当前系统频繁查询商品分类、热门商品等静态数据 优化方案:集成Redis作为二级缓存,减少数据库压力

@Service
public class ProductServiceWithCache {
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private ProductDAO productDAO;
    
    private static final String CATEGORY_CACHE_KEY = "product:categories";
    private static final long CACHE_EXPIRE = 3600; // 1小时
    
    public List<Category> getCategories() {
        // 先查缓存
        List<Category> categories = (List<Category>) redisTemplate.opsForValue().get(CATEGORY_CACHE_KEY);
        if (categories == null) {
            // 缓存未命中,查询数据库
            categories = productDAO.findAllCategories();
            // 写入缓存
            redisTemplate.opsForValue().set(CATEGORY_CACHE_KEY, categories, CACHE_EXPIRE, TimeUnit.SECONDS);
        }
        return categories;
    }
}

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

应用场景:订单创建后的库存扣减、短信通知、日志记录等操作 **

本文关键词
SSM框架在线车辆销售交易平台源码解析数据库设计

上下篇

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