十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

校园二手交易平台开发实战:Spring Boot+MyBatis-Plus技术整合与业务实现

校园二手交易平台开发实战:Spring Boot+MyBatis-Plus技术整合与业务实现 简介在Java Web开发领域掌握企业级应用架构是进阶的关键。MVC分层架构通过分离模型、视图与控制器的职责实现了代码的高内聚与低耦合是构建可维护性系统的基石。其技术价值在于能够清晰组织业务逻辑提升团队协作效率并支撑复杂业务场景的灵活扩展。在电商、社交、内容管理等实际应用中这种架构模式尤为常见。本文聚焦于校园二手交易这一典型场景深入探讨如何运用Spring Boot快速搭建项目骨架并借助MyBatis-Plus高效处理数据持久化解决商品交易中的并发与数据一致性问题为初学者提供一个从理论到实践的完整技术整合范例。1. 项目概述与核心价值“校园二手交易市场”这个项目对于大二计算机相关专业的学生来说绝对是一个“黄金级”的练手项目。它不像一个简单的计算器或者管理系统那样单薄也不至于复杂到像电商平台那样让人望而生畏。它恰好卡在一个“跳一跳够得着”的甜点区能让你把大一、大二学到的Java SE、数据库、Web基础等知识进行一次系统性的串联和实战检验。我当年做类似项目时最大的感受就是纸上得来终觉浅绝知此事要躬行。课本上的List、Map、JDBC、Servlet只有当你真正用它们去解决“用户发布商品”、“生成订单”、“处理支付哪怕是模拟”这些具体业务时你才能深刻理解面向对象设计、MVC分层、数据库事务这些概念到底意味着什么。这个项目的核心价值远不止于完成一个作业。首先它是一个绝佳的技术整合实践场。你需要考虑前端页面如何与后端交互JSP/Thymeleaf vs. 前后端分离数据如何持久化MySQL表设计业务逻辑如何组织Service层设计以及如何管理用户会话Session/Cookie。其次它直接关联真实的业务场景。你会遇到并发问题两个用户同时购买最后一个商品怎么办、数据一致性问题扣了库存但订单没生成成功怎么办、用户体验问题图片如何上传和展示搜索功能怎么做。思考并尝试解决这些问题的过程就是你从“学生”向“初级开发者”蜕变的关键一步。最后它也是你简历上第一个像样的项目。一个功能完整、设计清晰的二手市场项目在面试中能够清晰地展示你的编程能力、设计思维和解决问题的能力比空洞地罗列技术栈要强得多。2. 项目整体架构与技术选型思路接到“校园二手交易市场”这个需求我们首先要确定技术栈。对于大二小学期这个阶段我的建议是优先选择经典、稳定、资料丰富的技术组合把重点放在业务逻辑实现和架构理解上而不是追逐最新、最炫的框架。一个经过时间检验的技术栈能让你在遇到问题时更容易找到解决方案。2.1 后端技术栈选型核心语言Java 8/11/17Java 8依然是企业级应用的主流Lambda和Stream API能极大简化代码。如果教学环境允许使用Java 11或17可以获得更好的性能和新特性但务必确认你的IDE和依赖库兼容。这是基础没得商量。Web框架Spring Boot 2.x这是最核心的选择。为什么是Spring Boot而不是传统的SSHStruts2SpringHibernate或者纯Servlet因为Spring Boot极大地简化了配置让你能快速搭建一个可运行的、生产就绪的应用程序。它内嵌了Tomcat服务器你只需要一个main方法就能启动项目避免了繁琐的XML配置和外部服务器部署可以把精力集中在业务开发上。对于初学者这是从“混沌”到“规范”的最佳引路人。数据访问层MyBatis-Plus持久层框架主要有两个方向JPA如Spring Data JPA和MyBatis。JPA更面向对象通过操作实体类来操作数据库但复杂查询的灵活性稍弱。MyBatis则通过XML或注解写SQL灵活性高。我推荐MyBatis-Plus它是MyBatis的增强工具在保留MyBatis所有特性的基础上提供了强大的CRUD封装你几乎不用写简单的增删改查SQL、分页插件、代码生成器等能极大提升开发效率。对于需要复杂联表查询的二手市场业务如查询商品时同时关联用户信息、分类信息MyBatis写SQL的方式更直观可控。数据库MySQL 8.0关系型数据库的不二之选。校园二手市场的数据关系明确用户、商品、订单、分类等适合用关系模型来设计。MySQL 8.0在性能、JSON支持和窗口函数等方面比5.7有显著提升。务必学会使用utf8mb4字符集以支持完整的Emoji表情这在商品描述和聊天中很常见。项目管理与构建Maven用于管理项目依赖Jar包、构建和打包。相比GradleMaven的XML配置方式更直观国内资料和镜像资源也更丰富适合入门。2.2 前端技术栈选型这里有两个主流方向需要根据你的课程要求和兴趣权衡方案A传统模板引擎JSP / Thymeleaf这是前后端不分离的架构。后端Spring Boot不仅处理数据和逻辑还负责渲染HTML页面通过JSP或Thymeleaf模板并将完整的页面返回给浏览器。优点学习曲线平缓你只需要关注Java和后端模板语法无需额外学习前端框架。项目结构简单易于调试错误信息都在后端。缺点前后端耦合紧密不利于后期维护和扩展。页面交互体验较差每次操作都可能需要整页刷新。建议如果你的课程重点在Java后端且时间有限选择Thymeleaf。它语法更自然与HTML5兼容性好是Spring Boot官方推荐的首选模板引擎。方案B前后端分离Vue.js / React Spring Boot API这是现代Web开发的主流模式。后端Spring Boot只提供RESTful API接口返回JSON数据。前端是一个独立的工程使用Vue.js或React负责页面渲染和用户交互通过Ajax调用后端API获取数据。优点前后端职责清晰并行开发效率高。前端用户体验好可以实现局部刷新、动态交互。后端API可以被多种客户端Web、App、小程序复用。缺点学习成本较高你需要同时学习前端框架和RESTful API设计。开发环境搭建和联调稍复杂。建议如果你有前端基础或者想挑战自己、做一个更“现代化”的项目强烈推荐此方案。Vue.js因其易于上手、文档友好是学生项目的热门选择。后端则专注于设计和实现一套清晰的REST API。个人心得我指导过很多学生项目。如果这是你第一个综合性Java Web项目我建议从Thymeleaf开始。它能让你快速看到成果建立信心并深刻理解HTTP请求-响应的完整周期。当你用Thymeleaf完成核心功能后可以尝试将其中一部分比如商品列表页改造成Vue.js API的形式体验前后端分离的差异这样的学习路径更平滑。2.3 辅助工具与技术版本控制Git。必须使用在GitHub或Gitee上创建仓库每完成一个功能就提交一次。这是团队协作和代码回溯的生命线。IDEIntelliJ IDEA Ultimate (学生可免费申请)或Eclipse。IDEA对Spring Boot和Java的支持更智能、更高效。API测试Postman或Insomnia。用于测试你编写的后端REST API接口比用浏览器或写前端代码测试要方便得多。数据库可视化工具Navicat Premium或DBeaver。用于直观地管理MySQL数据库执行SQL语句查看表结构。3. 核心功能模块设计与数据库建模一个完整的校园二手交易市场核心是“交易”围绕交易会产生几个关键实体人用户、物商品、交易凭证订单。此外还需要一些支撑系统如分类、消息、评价等。3.1 数据库表结构设计设计数据库是项目的基石。良好的设计能让你后续的编码事半功倍。以下是核心表的设计思路字段为示例可根据需求增减1. 用户表 (user)这是系统的基石。除了基础信息要重点考虑安全和状态。CREATE TABLE user ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, username varchar(50) NOT NULL COMMENT 用户名用于登录, password varchar(255) NOT NULL COMMENT 加密后的密码, student_id varchar(20) DEFAULT NULL UNIQUE COMMENT 学号, nickname varchar(50) DEFAULT NULL COMMENT 昵称用于显示, avatar_url varchar(500) DEFAULT NULL COMMENT 头像图片URL, phone varchar(20) DEFAULT NULL COMMENT 手机号, email varchar(100) DEFAULT NULL COMMENT 邮箱, campus varchar(100) DEFAULT NULL COMMENT 校区, dormitory varchar(100) DEFAULT NULL COMMENT 宿舍楼, credit_score int(11) DEFAULT 100 COMMENT 信用分用于评价体系, status tinyint(4) DEFAULT 1 COMMENT 状态0-禁用1-正常, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;注意password字段绝对不能明文存储必须使用Spring Security的BCryptPasswordEncoder进行单向哈希加密。credit_score可以设计一个简单的规则如成功交易一次1被差评-5等增加平台可信度。2. 商品分类表 (category)用于对商品进行归类如书籍、数码、衣物、日用等。采用简单的父子级结构即可。CREATE TABLE category ( id int(11) NOT NULL AUTO_INCREMENT, parent_id int(11) DEFAULT 0 COMMENT 父级分类ID0表示一级分类, name varchar(50) NOT NULL COMMENT 分类名称, sort_order int(11) DEFAULT 0 COMMENT 排序, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品分类表;3. 商品表 (product)这是核心业务表。字段设计要能完整描述一件二手商品。CREATE TABLE product ( id bigint(20) NOT NULL AUTO_INCREMENT, seller_id bigint(20) NOT NULL COMMENT 卖家用户ID, category_id int(11) NOT NULL COMMENT 分类ID, title varchar(200) NOT NULL COMMENT 商品标题, description text COMMENT 商品详情描述, price decimal(10,2) NOT NULL COMMENT 价格, original_price decimal(10,2) DEFAULT NULL COMMENT 原价, cover_image varchar(500) DEFAULT NULL COMMENT 封面图URL, image_urls json DEFAULT NULL COMMENT 商品图片URL列表JSON数组格式, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 状态0-待审核1-出售中2-已售出3-已下架, view_count int(11) DEFAULT 0 COMMENT 浏览量, like_count int(11) DEFAULT 0 COMMENT 点赞/收藏数, campus varchar(100) DEFAULT NULL COMMENT 商品所在校区, transaction_mode tinyint(4) DEFAULT 1 COMMENT 交易方式1-线下自提2-线上快递, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_seller (seller_id), KEY idx_category (category_id), KEY idx_status (status), FULLTEXT KEY ft_title_desc (title, description) -- 全文索引用于搜索 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品表;关键点image_urls字段使用JSON类型存储图片数组比用逗号分隔的字符串更规范方便前端直接解析。MySQL 5.7以上支持JSON类型。status字段的状态流转是业务核心逻辑需要在代码中严格控制例如已售出的商品不能修改。创建了FULLTEXT全文索引为后续实现搜索功能做准备。对于数据量不大的校园场景这比LIKE %关键词%高效得多。4. 订单表 (order)交易的核心凭证。注意表名order是SQL关键字最好用反引号包裹或使用order_info。CREATE TABLE order ( id varchar(32) NOT NULL COMMENT 订单号使用自定义规则生成如时间戳随机数, buyer_id bigint(20) NOT NULL COMMENT 买家ID, seller_id bigint(20) NOT NULL COMMENT 卖家ID, product_id bigint(20) NOT NULL COMMENT 商品ID, product_snapshot json NOT NULL COMMENT 下单时的商品快照标题、价格、图片等防止商品信息后续修改, total_amount decimal(10,2) NOT NULL COMMENT 订单总金额, order_status tinyint(4) NOT NULL DEFAULT 0 COMMENT 订单状态0-待支付1-已支付/待发货2-已发货/待收货3-交易完成4-已取消5-退款中, payment_method tinyint(4) DEFAULT NULL COMMENT 支付方式1-余额2-微信3-支付宝, transaction_id varchar(100) DEFAULT NULL COMMENT 第三方支付交易号, delivery_mode tinyint(4) DEFAULT NULL COMMENT 交付方式1-线下自提2-快递, delivery_address varchar(500) DEFAULT NULL COMMENT 收货地址快递时用, meetup_location varchar(200) DEFAULT NULL COMMENT 线下见面地点, buyer_notes varchar(500) DEFAULT NULL COMMENT 买家留言, create_time datetime DEFAULT CURRENT_TIMESTAMP, pay_time datetime DEFAULT NULL COMMENT 支付时间, finish_time datetime DEFAULT NULL COMMENT 完成时间, PRIMARY KEY (id), KEY idx_buyer (buyer_id), KEY idx_seller (seller_id), KEY idx_product (product_id), KEY idx_create_time (create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单表;核心设计product_snapshot字段至关重要它使用JSON格式保存下单那一刻的商品关键信息标题、价格、封面图等。这是因为商品信息可能会被卖家修改如果不保存快照用户看到的订单历史信息就可能和购买时不一致引发纠纷。这是电商类系统的通用设计。5. 聊天/消息表 (message)实现买卖家沟通。CREATE TABLE message ( id bigint(20) NOT NULL AUTO_INCREMENT, sender_id bigint(20) NOT NULL COMMENT 发送者ID, receiver_id bigint(20) NOT NULL COMMENT 接收者ID, product_id bigint(20) DEFAULT NULL COMMENT 关联的商品ID可为空, content text NOT NULL COMMENT 消息内容, msg_type tinyint(4) DEFAULT 1 COMMENT 消息类型1-文本2-图片, is_read tinyint(1) DEFAULT 0 COMMENT 是否已读0-未读1-已读, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_conversation (sender_id, receiver_id, product_id), -- 优化查询双方关于某商品的对话 KEY idx_receiver_unread (receiver_id, is_read) -- 优化查询未读消息 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT消息表;3.2 后端工程结构设计基于Spring Boot采用经典的分层架构职责清晰便于维护。src/main/java/com/campusmarket/ ├── CampusMarketApplication.java # Spring Boot 主启动类 ├── config/ # 配置类 │ ├── WebMvcConfig.java # MVC配置如拦截器、静态资源 │ ├── MybatisPlusConfig.java # MyBatis-Plus分页插件等配置 │ └── ... ├── controller/ # 控制层接收请求返回响应 │ ├── api/ # REST API接口如果前后端分离 │ │ ├── ProductController.java │ │ └── UserController.java │ └── web/ # 页面控制器如果用Thymeleaf │ └── ... ├── service/ # 业务逻辑层 │ ├── impl/ # 业务逻辑实现类 │ │ ├── ProductServiceImpl.java │ │ └── UserServiceImpl.java │ └── ProductService.java # 业务接口 ├── mapper/ # 数据访问层MyBatis Mapper接口 │ ├── ProductMapper.java │ └── UserMapper.java ├── entity/ # 实体类与数据库表对应 │ ├── Product.java │ └── User.java ├── dto/ # 数据传输对象用于前后端交互 │ ├── ProductDTO.java │ └── LoginDTO.java ├── vo/ # 视图对象用于页面展示 │ └── ProductDetailVO.java ├── util/ # 工具类 │ ├── JsonUtil.java │ └── OrderNoGenerator.java # 订单号生成器 └── exception/ # 自定义异常 └── BusinessException.java4. 关键业务逻辑实现与避坑指南有了清晰的设计接下来就是编码实现。这里挑几个最容易出问题、也最能体现你编程功力的核心业务点来讲。4.1 用户认证与会话管理需求用户注册、登录、登出并在登录后保持会话状态。实现使用Spring Session将用户会话信息存储到Redis或数据库中实现分布式会话管理即使你目前是单机这也是好习惯。更简单的方式是使用Servlet原生的HttpSession。避坑指南密码加密前面提到过必须用BCryptPasswordEncoder。注册时加密存储登录时用它匹配。千万不要自己写MD5/SHA加密。会话超时与安全在application.properties中配置server.servlet.session.timeout180030分钟。对于敏感操作如支付、修改密码即使会话有效也应再次验证密码二次确认。登录状态拦截编写一个HandlerInterceptor在preHandle方法中检查Session里是否存在用户信息。如果没有则重定向到登录页。记得在配置中排除登录、注册、静态资源等路径。4.2 商品发布与图片上传需求用户填写表单上传图片发布商品。实现表单使用multipart/form-data编码。后端使用Spring的MultipartFile接收文件。将文件保存到服务器本地目录如/upload或对象存储如阿里云OSS、腾讯云COS更推荐但需要学习成本。生成一个可访问的URL存到数据库。避坑指南文件重名上传前一定要对文件名进行重命名通常使用UUID如UUID.randomUUID() 文件后缀避免覆盖和冲突。文件类型检查在后台校验文件扩展名和MIME类型防止上传恶意脚本。只允许jpg, png, gif等图片格式。图片处理用户上传的图片可能很大。可以使用Thumbnails等库生成缩略图用于列表页展示原图用于详情页。这能极大提升页面加载速度。路径问题保存的路径D:/upload/xxx.jpg和通过Web访问的路径/upload/xxx.jpg不是一回事。你需要配置静态资源映射让Spring Boot能正确提供这些上传的文件。例如Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 将本地文件路径映射到网络URL路径 registry.addResourceHandler(/upload/**) .addResourceLocations(file:D:/workspace/upload/); } }4.3 商品交易与库存状态一致性这是整个系统最核心、最容易出错的业务逻辑。场景用户A点击“立即购买”一件仅剩1库存的商品。问题如果同时有用户B也点击购买可能会产生“超卖”一件商品卖给两个人。解决方案悲观锁或乐观锁。悲观锁Pessimistic Lock在查询商品时就用SELECT ... FOR UPDATE锁定这条记录直到当前事务提交。其他事务必须等待。这种方式简单粗暴能保证强一致性但并发性能差容易死锁。对于校园二手市场这种并发量不高的场景可以考虑。// 在ProductMapper接口中定义 Select(SELECT * FROM product WHERE id #{id} FOR UPDATE) Product selectForUpdate(Long id); // 在Service方法中先锁住商品再判断状态和库存然后更新乐观锁Optimistic Lock更推荐。在商品表中增加一个version版本号字段。更新时带上版本号条件。UPDATE product SET status #{newStatus}, version version 1 WHERE id #{id} AND version #{oldVersion} AND status #{oldStatus};执行后检查update语句影响的条数。如果为0说明更新失败被别人抢先修改了此时应该抛出异常或返回错误信息给用户提示“商品信息已变化请刷新重试”。实操心得乐观锁的实现需要前后端配合。前端在提交购买请求时需要把当前看到的商品版本号也传过来。后端更新失败后应返回明确的错误码前端根据错误码提示用户刷新页面。这比直接显示一个“系统错误”友好得多。4.4 订单流程与状态机订单状态order_status的流转必须有严格的逻辑控制不能随意修改。这非常适合用“状态模式”或简单的枚举条件判断来实现。状态流转图简化版待支付 (0) --[用户支付]-- 已支付/待发货 (1) 已支付/待发货 (1) --[卖家发货]-- 已发货/待收货 (2) 已发货/待收货 (2) --[买家确认收货]-- 交易完成 (3) 待支付 (0) --[用户取消/超时未支付]-- 已取消 (4) 其他状态如退款流程可后续扩展实现要点在OrderService中为每个状态变更操作如payOrder,shipOrder,confirmOrder编写独立的方法。在每个方法内部首先根据订单ID查询当前订单和状态。进行前置状态校验例如shipOrder方法必须检查当前状态是否为“已支付/待发货(1)”否则抛出BusinessException。校验通过后再执行更新操作并记录相关时间如pay_time,finish_time。状态变更后可以触发相应事件如发送站内信或邮件通知买卖双方。5. 典型问题排查与性能优化实践在开发过程中你一定会遇到各种“坑”。这里记录几个最常见的问题和解决思路。5.1 数据库连接超时与连接池配置现象项目运行一段时间后偶尔会出现Communications link failure或Connection is not available的错误。原因数据库连接被占用后没有正确释放或者连接池配置不合理。解决方案确保资源关闭在MyBatis中确保你的SqlSession在finally块中关闭或者使用try-with-resources语法。但更常见的是使用Spring管理的SqlSessionTemplate它会自动处理。配置合适的连接池Spring Boot默认使用HikariCP性能很好。在application.yml中调整其参数spring: datasource: hikari: maximum-pool-size: 20 # 根据你的数据库和服务器性能调整通常10-20足够 minimum-idle: 5 connection-timeout: 30000 # 连接超时时间(ms) idle-timeout: 600000 # 连接空闲超时时间(ms)超时后释放 max-lifetime: 1800000 # 连接最大生命周期(ms) connection-test-query: SELECT 1 # 用于验证连接的有效性的查询检查MySQL的wait_timeoutMySQL服务器端会关闭长时间空闲的连接默认8小时。确保你的连接池的max-lifetime小于MySQL的wait_timeout。5.2 事务管理不当导致数据不一致现象在发布商品涉及插入商品记录和更新用户商品数或交易涉及扣库存、创建订单、更新用户余额时部分操作成功部分失败数据出现不一致。原因没有使用事务或者事务的传播行为配置错误。解决方案在Service层方法上添加Transactional注解。这是声明式事务管理Spring会帮你处理事务的开启、提交和回滚。Service public class ProductServiceImpl implements ProductService { Override Transactional(rollbackFor Exception.class) // 发生任何异常都回滚 public boolean publishProduct(ProductDTO dto) { // 1. 保存商品信息 productMapper.insert(product); // 2. 更新用户的商品计数 userMapper.incrementProductCount(dto.getSellerId()); // 如果第二步失败第一步插入的商品也会被回滚 return true; } }理解默认的传播行为REQUIRED如果当前没有事务就新建一个事务如果已经存在一个事务就加入这个事务。这对于大多数业务方法都是合适的。小心非受检异常RuntimeException默认情况下只有运行时异常和Error会导致回滚。受检异常如IOException不会。如果你希望所有异常都回滚就像上面代码一样加上rollbackFor Exception.class。5.3 分页查询性能问题现象商品列表页当数据量达到几千条时翻到后面几页速度变慢。原因使用了LIMIT offset, size进行深分页。例如LIMIT 10000, 20MySQL需要先扫描前10020条记录然后扔掉前10000条返回最后的20条效率低下。解决方案使用MyBatis-Plus的分页插件它帮你封装了分页逻辑并且默认使用优化后的COUNT查询。// 配置分页插件 Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } // 使用分页 PageProduct page new Page(currentPage, pageSize); PageProduct result productMapper.selectPage(page, queryWrapper);深分页优化对于非常深的分页比如第1000页LIMIT性能很差。可以考虑“游标分页”或“基于ID的分页”。基于ID的分页要求列表按ID或时间戳排序。查询下一页时不传页码而是传上一页最后一条记录的ID。-- 传统分页 SELECT * FROM product ORDER BY create_time DESC LIMIT 10000, 20; -- 基于ID的分页假设上一页最后一条记录的id是 12345 SELECT * FROM product WHERE id 12345 ORDER BY id DESC LIMIT 20;这种方式利用了索引效率极高。但缺点是无法直接跳转到任意页码。5.4 前端页面数据渲染与循环依赖现象在使用Thymeleaf时页面模板中循环显示商品列表但某个商品属性如卖家昵称需要额外查询导致在循环内频繁访问数据库N1问题。解决方案在Service层做好数据组装查询商品列表时使用一条SQL通过LEFT JOIN将卖家信息一并查询出来避免在循环中再次查询。// ProductMapper.xml select idselectProductWithUser resultMapProductWithUserMap SELECT p.*, u.nickname as seller_nickname, u.avatar_url as seller_avatar FROM product p LEFT JOIN user u ON p.seller_id u.id WHERE p.status 1 ORDER BY p.create_time DESC /select使用DTO或VO对象不要直接将Product实体返给前端。创建一个ProductVOView Object在里面增加sellerNickname、sellerAvatar等字段在Service层查询并填充好这个VO对象列表再返回给Controller。这样模板里直接取用即可逻辑清晰性能也好。6. 项目部署与后期扩展思考完成开发后你需要让项目跑起来供他人访问。6.1 本地运行与打包配置application.yml将数据库连接、文件上传路径等配置从代码中分离出来。创建application-dev.yml开发环境和application-prod.yml生产环境通过Spring的spring.profiles.active属性切换。使用Maven打包在项目根目录执行mvn clean package -DskipTests。会在target目录下生成一个可执行的Jar包如campus-market-0.0.1-SNAPSHOT.jar。运行在服务器上或本地使用命令java -jar campus-market-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod即可启动。内嵌的Tomcat会启动默认端口8080。6.2 简易服务器部署以Linux为例环境准备确保服务器已安装Java运行环境JRE 8或11、MySQL数据库。上传与运行使用FTP或SCP将Jar包上传到服务器。使用nohup命令让程序在后台运行nohup java -jar campus-market-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod app.log 21 。这样日志会输出到app.log文件。使用Nginx做反向代理直接暴露8080端口不专业。安装Nginx配置一个server块将80端口的请求代理到本地的8080端口。这样用户就可以通过域名或IP直接访问了无需加端口号。server { listen 80; server_name your-domain.com; # 你的域名或IP location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 静态资源如图片也可以由Nginx直接处理减轻Java应用压力 location /upload/ { alias /path/to/your/upload/dir/; } }6.3 可能的扩展方向如果你有余力可以为这个项目增加更多亮点全文搜索集成Elasticsearch实现更强大、更快速的商品搜索支持拼音、错别字纠正等。WebSocket实时聊天将站内信升级为真正的实时在线聊天提升用户体验。可以使用Spring Boot集成的WebSocket或更成熟的Netty框架。微信小程序端由于后端已经是RESTful API你可以非常方便地开发一个微信小程序前端让交易更便捷。简单的推荐系统基于用户的浏览记录和购买记录使用协同过滤算法在首页实现“猜你喜欢”。后台管理系统为管理员开发一个独立的后台用于管理用户、审核商品、处理投诉等。完成这个项目你收获的将不仅仅是一个“校园二手交易市场.zip”压缩包而是一整套从需求分析、设计、编码、调试到部署的完整项目经验。这些经验以及你在过程中培养出来的解决问题、查阅文档、调试代码的能力才是你未来求职和深造中最宝贵的财富。动手开始做吧遇到问题就搜索、就请教每一个踩过的坑都会让你变得更强大。本文还有配套的精品资源点击获取
返回列表