1. 项目概述
这个基于Java+SpringBoot+SSM的旧物回收商城系统,是我在开发实践中遇到的一个典型电商类项目。随着环保意识的提升和共享经济的发展,二手物品交易平台的需求日益增长。这个系统正是为了解决个人闲置物品流转、促进资源循环利用而设计的。
系统采用了前后端分离的架构模式,前端使用Spring+SpringMVC+Mybatis(SSM)框架组合,后端基于SpringBoot+Mybatis构建。数据库支持MySQL和SQLServer两种主流关系型数据库,开发工具选用IDEA/Eclipse配合Navicat进行数据库管理。
2. 技术选型解析
2.1 前端技术栈
SpringMVC作为SSM框架中的核心组件,在这个项目中承担了重要的控制器角色。它实现了经典的MVC设计模式,将业务逻辑与视图展示清晰地分离。在实际开发中,我发现SpringMVC的注解驱动特性大大简化了开发流程:
java复制@Controller
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
@GetMapping("/list")
public String list(Model model) {
model.addAttribute("goodsList", goodsService.findAll());
return "goods/list";
}
}
这种基于注解的配置方式,相比传统的XML配置更加直观和易于维护。特别是@RequestMapping注解,可以灵活地定义URL映射关系,支持RESTful风格的API设计。
2.2 后端技术栈
SpringBoot作为后端框架的选择,主要考虑了以下几个因素:
- 自动配置特性减少了大量样板代码
- 内嵌Tomcat服务器简化了部署流程
- Starter依赖机制让项目依赖管理更加清晰
- Actuator提供了完善的应用监控能力
在实际开发中,我特别欣赏SpringBoot的"约定优于配置"理念。例如,数据库连接池的配置,传统方式需要手动配置各种参数,而在SpringBoot中只需简单的配置:
properties复制spring.datasource.url=jdbc:mysql://localhost:3306/recycle_mall
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3. 核心功能实现
3.1 商品管理模块
商品管理是系统的核心功能之一,主要包括商品发布、商品展示、商品搜索等功能。在数据库设计上,我们采用了以下表结构:
sql复制CREATE TABLE `goods` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL COMMENT '发布用户ID',
`category_id` int(11) NOT NULL COMMENT '分类ID',
`title` varchar(100) NOT NULL COMMENT '商品标题',
`price` decimal(10,2) NOT NULL COMMENT '价格',
`original_price` decimal(10,2) DEFAULT NULL COMMENT '原价',
`description` text COMMENT '商品描述',
`images` varchar(1000) DEFAULT NULL COMMENT '图片URL,多个用逗号分隔',
`status` tinyint(4) DEFAULT '1' COMMENT '状态:1-上架,0-下架',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
提示:在设计商品表时,特别注意了索引的建立。
user_id和category_id都建立了索引,这对提高查询性能至关重要。
3.2 交易流程设计
交易流程是系统的另一个核心功能,主要包括下单、支付、物流、评价等环节。我们采用了状态机模式来管理订单状态:
java复制public enum OrderStatus {
UNPAID(1, "待支付"),
PAID(2, "已支付"),
SHIPPED(3, "已发货"),
COMPLETED(4, "已完成"),
CANCELLED(5, "已取消"),
REFUNDED(6, "已退款");
// 省略构造函数和getter方法
}
状态转换通过策略模式实现,确保状态变更的合法性和可追溯性:
java复制public interface OrderStateHandler {
Order handle(Order order, OrderAction action);
}
@Service
public class PaidStateHandler implements OrderStateHandler {
@Override
public Order handle(Order order, OrderAction action) {
if (action == OrderAction.SHIP) {
order.setStatus(OrderStatus.SHIPPED.getCode());
// 触发发货逻辑
}
// 其他处理...
return order;
}
}
4. 系统架构设计
4.1 分层架构
系统采用经典的三层架构设计:
- 表现层:处理HTTP请求和响应,包括Controller和View
- 业务逻辑层:实现核心业务逻辑,Service层
- 数据访问层:负责数据持久化,DAO/Mapper层
这种分层设计使得系统职责清晰,便于维护和扩展。特别是在处理复杂业务时,各层之间的接口定义尤为重要。例如,商品搜索功能的接口设计:
java复制public interface GoodsSearchService {
Page<GoodsVO> search(GoodsSearchDTO searchDTO);
List<GoodsCategoryVO> getHotCategories();
List<GoodsVO> getRecommendGoods(Long userId);
}
4.2 缓存策略
为了提高系统性能,我们采用了多级缓存策略:
- 本地缓存:使用Caffeine缓存热点数据
- 分布式缓存:Redis集群缓存共享数据
- 数据库缓存:合理使用MySQL查询缓存
缓存更新采用"先更新数据库,再删除缓存"的策略,避免缓存一致性问题:
java复制@Transactional
public void updateGoods(Goods goods) {
// 1. 更新数据库
goodsMapper.updateById(goods);
// 2. 删除缓存
redisTemplate.delete("goods:" + goods.getId());
// 3. 异步更新搜索引擎
searchService.asyncUpdateIndex(goods);
}
5. 安全设计
5.1 认证与授权
系统采用JWT(JSON Web Token)进行身份认证,结合Spring Security实现权限控制。核心配置如下:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}
}
5.2 数据安全
对于敏感数据如用户手机号、地址等,我们采用了加密存储策略:
java复制public String encrypt(String data) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception e) {
throw new RuntimeException("加密失败", e);
}
}
6. 性能优化
6.1 数据库优化
针对商品列表查询这类高频操作,我们做了以下优化:
- 使用覆盖索引减少回表操作
- 合理使用JOIN替代子查询
- 对大表进行分库分表
例如,商品列表查询SQL优化前后对比:
sql复制-- 优化前
SELECT * FROM goods WHERE category_id = ? ORDER BY create_time DESC;
-- 优化后
SELECT id, title, price, images FROM goods
WHERE category_id = ?
ORDER BY create_time DESC
LIMIT 20;
6.2 接口性能优化
对于高并发接口,我们采用了以下策略:
- 异步处理非核心流程
- 接口限流防止系统过载
- 结果缓存减少重复计算
使用Guava RateLimiter实现简单限流:
java复制private final RateLimiter rateLimiter = RateLimiter.create(100.0); // 每秒100个请求
@GetMapping("/hot")
public Result<List<GoodsVO>> getHotGoods() {
if (!rateLimiter.tryAcquire()) {
throw new BusinessException("请求过于频繁,请稍后再试");
}
return Result.success(goodsService.getHotGoods());
}
7. 部署方案
7.1 容器化部署
系统采用Docker容器化部署,便于环境一致性和扩展。核心Dockerfile配置:
dockerfile复制FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
使用docker-compose编排多个服务:
yaml复制version: '3'
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- redis
- mysql
redis:
image: redis:alpine
ports:
- "6379:6379"
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: recycle_mall
ports:
- "3306:3306"
7.2 监控与日志
系统集成Prometheus和Grafana进行监控,ELK收集和分析日志。关键指标包括:
- 接口响应时间
- 系统吞吐量
- JVM内存使用情况
- 数据库连接池状态
SpringBoot配置Prometheus监控:
properties复制management.endpoints.web.exposure.include=health,info,prometheus
management.metrics.tags.application=recycle-mall
8. 开发心得与避坑指南
在实际开发过程中,我积累了一些宝贵的经验:
-
MyBatis使用技巧:
- 使用
<resultMap>避免N+1查询问题 - 动态SQL优先使用
<if>标签而非Java代码拼接 - 批量操作使用
<foreach>标签
- 使用
-
事务管理要点:
- 合理设置事务隔离级别和传播行为
- 避免在事务方法中进行远程调用
- 注意事务失效的常见场景(如自调用)
-
性能优化经验:
- 列表查询一定要分页
- 避免在循环中访问数据库
- 合理使用二级缓存
-
团队协作建议:
- 统一异常处理规范
- 制定清晰的接口文档标准
- 建立代码审查机制
注意:在开发商品搜索功能时,初期直接使用LIKE进行模糊查询,导致性能极差。后来改用Elasticsearch实现全文检索,性能提升显著。这个教训告诉我们,技术选型要根据实际场景需求来决定。
9. 扩展与演进
系统未来可以考虑的扩展方向:
- 多端适配:开发微信小程序、APP等客户端
- 智能推荐:基于用户行为数据实现个性化推荐
- 信用体系:建立用户信用评价机制
- 物流跟踪:集成第三方物流接口实现实时跟踪
- 区块链应用:使用区块链技术确保交易不可篡改
技术演进路线:
- 微服务化改造,解耦核心功能
- 引入Service Mesh治理服务间通信
- 采用云原生技术栈提升弹性伸缩能力
- 实现多活架构保证高可用性
这个旧物回收商城系统从技术选型到架构设计,再到具体实现,每个环节都经过深思熟虑。在实际开发中,最大的体会是:没有最好的技术,只有最适合的技术。根据项目规模、团队能力和业务需求做出合理的技术决策,比盲目追求新技术更为重要。