这个基于Java SpringBoot+Vue3+MyBatis的环保网站系统,是我去年为某环保组织开发的核心项目。整套系统采用前后端分离架构,前端使用Vue3组合式API开发,后端基于SpringBoot 2.7整合MyBatis-Plus,数据库选用MySQL 8.0。系统主要包含环保资讯发布、活动报名、碳足迹计算、环保知识库等模块,日均承载2W+访问量。
在技术选型上,Vue3的Composition API让前端组件逻辑更清晰,搭配Pinia状态管理替代了传统的Vuex;后端采用SpringBoot快速构建RESTful API,MyBatis-Plus的Lambda表达式让数据库操作更优雅;MySQL配置了读写分离和定时备份策略保障数据安全。整个项目从零开始搭建到上线历时3个月,期间解决了前后端鉴权、大文件上传、高并发查询等多个技术难点。
提示:这类企业级项目建议使用Maven多模块管理,将domain、dao、service、controller分层明确,避免后期维护混乱
后端采用经典的MVC分层架构:
code复制环保系统
├── eco-common // 公共模块
├── eco-domain // 实体类
├── eco-dao // MyBatis映射
├── eco-service // 业务逻辑
└── eco-web // 控制器
数据库连接池选用HikariCP,配置示例如下:
yaml复制spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/eco_db?useSSL=false&serverTimezone=UTC
username: root
password: 加密后的密码
hikari:
maximum-pool-size: 20
connection-timeout: 30000
特别要注意的是:
前端采用Vite4构建工具,相比Webpack启动速度快了5-8倍。主要依赖包括:
json复制"dependencies": {
"vue": "^3.2.47",
"pinia": "^2.0.33",
"element-plus": "^2.3.3",
"axios": "^1.3.4",
"echarts": "^5.4.2"
}
路由配置采用懒加载提升首屏速度:
javascript复制const routes = [
{
path: '/news',
component: () => import('@/views/News.vue'),
meta: { requiresAuth: true }
}
]
踩坑记录:Vue3中使用Element Plus的表单验证时,必须用reactive()包裹表单对象,否则校验会失效
核心表包括:
sql复制CREATE TABLE `eco_article` (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`content` text,
`view_count` int DEFAULT '0',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
FULLTEXT KEY `ft_idx` (`title`,`content`) -- 全文索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
索引优化方案:
在DAO层使用MyBatis-Plus的Lambda查询:
java复制public Page<Article> searchArticles(String keyword, int pageNum) {
return lambdaQuery()
.like(Article::getTitle, keyword)
.or()
.like(Article::getContent, keyword)
.orderByDesc(Article::getCreateTime)
.page(new Page<>(pageNum, 10));
}
事务管理示例:
java复制@Transactional(rollbackFor = Exception.class)
public void publishArticle(ArticleDTO dto) {
// 1. 保存文章
Article article = convertToEntity(dto);
articleMapper.insert(article);
// 2. 更新分类计数
categoryMapper.incrementCount(dto.getCategoryId());
}
java复制public String login(String username, String password) {
User user = userService.authenticate(username, password);
return Jwts.builder()
.setSubject(user.getId().toString())
.setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))
.signWith(SignatureAlgorithm.HS512, secretKey)
.compact();
}
javascript复制service.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
后端采用分块上传处理大文件:
java复制@PostMapping("/upload")
public Result upload(@RequestParam MultipartFile file) {
String filename = UUID.randomUUID() + getFileExtension(file);
Path path = Paths.get(uploadDir, filename);
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
return Result.success("/uploads/" + filename);
}
前端使用el-upload组件:
vue复制<el-upload
action="/api/upload"
:on-success="handleSuccess"
:before-upload="beforeUpload">
<el-button type="primary">点击上传</el-button>
</el-upload>
开发环境配置:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.maxAge(3600);
}
}
生产环境建议:
服务器最低配置:
使用Docker Compose部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- ./mysql-data:/var/lib/mysql
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
必备监控项:
日志收集配置示例:
xml复制<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
在项目实际运行中,我发现前端打包后的chunk文件过大问题,通过配置vite的manualChunks策略将node_modules单独打包,首屏加载时间从3.2秒降低到1.8秒。另外建议开启MySQL的慢查询日志,我们曾通过这个功能发现一个未加索引的查询语句,优化后接口响应时间从1200ms降到80ms。