1. 项目概述:SSM框架下的Web问卷调查系统
这个基于SSM框架的Web问卷调查系统是一个典型的Java EE企业级应用,采用Spring+SpringMVC+MyBatis的技术栈组合。我在实际开发中发现,这种架构特别适合需要快速迭代的中小型Web项目。系统核心功能包括问卷创建、问题设计、答卷收集和数据分析,整个开发周期大约需要2-3周(含调试)。
项目使用Maven进行依赖管理,前端采用JSP+Bootstrap的组合,这种技术选型保证了开发效率的同时也兼顾了界面美观。数据库方面选用MySQL 5.7+,主要考虑到其免费开源特性与SSM框架的良好兼容性。特别提醒:在环境搭建阶段就要确定好MySQL的字符集为utf8mb4,否则后期遇到emoji表情存储会出现乱码问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境配置与项目初始化
2.1 基础环境准备
开发环境建议使用IntelliJ IDEA 2024(社区版即可)+ JDK 1.8的组合。虽然新版的JDK也能运行,但1.8的稳定性经过长期验证。我遇到过在JDK11上运行SSM项目时出现的反射相关兼容性问题,最终回退到1.8才解决。
Maven配置需要注意:
xml复制<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.2.8.RELEASE</spring.version>
<mybatis.version>3.5.6</mybatis.version>
</properties>
2.2 SSM框架整合关键点
Spring与MyBatis的整合是项目基石,需要特别注意以下配置:
- 在applicationContext.xml中配置数据源时,建议使用Druid连接池而非基础的BasicDataSource
- MyBatis的SqlSessionFactoryBean需要显式指定mapperLocations
- 事务管理器的配置要包含对@Transactional注解的支持
一个常见的坑是Spring和MyBatis的版本兼容性问题。有次我使用了Spring 5.3.18配合MyBatis 3.5.7,结果出现了懒加载异常,最后锁定是mybatis-spring的bridge版本不匹配导致。
3. 数据库设计与实现
3.1 核心表结构设计
问卷系统的数据库设计遵循三范式原则,主要包含以下表:
- 问卷主表(questionnaire):存储问卷元信息
- 问题表(question):采用单表继承设计,通过question_type区分题型
- 选项表(option):与问题表一对多关联
- 答卷表(answer_sheet):记录提交信息
- 答案表(answer):采用纵表设计,便于扩展
sql复制CREATE TABLE `question` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`questionnaire_id` bigint(20) NOT NULL,
`question_type` tinyint(4) NOT NULL COMMENT '1-单选 2-多选 3-填空',
`content` varchar(500) NOT NULL,
`is_required` bit(1) NOT NULL DEFAULT b'0',
`order_num` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_questionnaire` (`questionnaire_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.2 MyBatis映射技巧
在MyBatis的Mapper设计中,我推荐使用注解与XML混合模式。对于简单CRUD使用注解,复杂查询使用XML。特别注意:
- 动态SQL尽量使用
标签而非直接写WHERE 1=1 - 结果映射推荐使用
而非自动映射 - 分页查询使用PageHelper插件而非手动limit
一个性能优化点:在查询问卷列表时,使用延迟加载关联的问题数据,避免N+1查询问题。
4. 核心功能实现细节
4.1 问卷创建模块
前端采用jQuery动态添加问题,后端接口设计遵循RESTful规范:
java复制@PostMapping("/questionnaires")
@ResponseBody
public Result createQuestionnaire(@Valid QuestionnaireDTO dto) {
// 验证逻辑
if(dto.getTitle().length() > 100) {
throw new BusinessException("问卷标题过长");
}
// 转换DTO到Entity
Questionnaire questionnaire = convertToEntity(dto);
// 保存操作
questionnaireService.create(questionnaire);
return Result.success(questionnaire.getId());
}
4.2 答卷提交处理
处理用户提交的答卷时需要注意:
- 防重复提交:采用Token机制
- 数据验证:服务端二次验证必填项
- 性能优化:批量插入答案记录
java复制@Transactional
public void submitAnswer(AnswerSheetDTO dto) {
// 1. 保存答卷主表
AnswerSheet sheet = convertToSheet(dto);
answerSheetMapper.insert(sheet);
// 2. 批量处理答案
List<Answer> answers = convertToAnswers(dto, sheet.getId());
answerMapper.batchInsert(answers); // 自定义批量插入方法
// 3. 更新问卷答卷数
questionnaireMapper.incrementAnswerCount(sheet.getQuestionnaireId());
}
5. 部署与运维实践
5.1 Tomcat部署优化
生产环境部署时,建议对Tomcat做以下配置调整:
- 连接器配置:启用NIO,设置合理的maxThreads
- JVM参数:根据服务器内存设置-Xms和-Xmx
- 访问日志:配置pattern记录必要信息
xml复制<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
minSpareThreads="20"
connectionTimeout="30000"
redirectPort="8443" />
5.2 常见问题排查
- 中文乱码问题:确保filter链中包含CharacterEncodingFilter
- 静态资源404:检查SpringMVC的resource mapping配置
- 事务不生效:确认方法是否为public且被Spring代理
我在实际部署中遇到过最棘手的问题是:在Linux环境下文件上传失败。最终发现是Tomcat临时目录权限问题,通过以下命令解决:
bash复制chown -R tomcat:tomcat /tmp/tomcat.*
chmod -R 755 /tmp/tomcat.*
6. 项目扩展与优化建议
6.1 性能优化方向
- 缓存策略:对热点问卷使用Redis缓存
- 异步处理:使用@Async处理统计计算
- 数据库优化:对answer表按问卷ID分表
6.2 功能扩展思路
- 增加微信小程序端:采用前后端分离架构
- 添加可视化分析:集成ECharts
- 支持问卷模板:设计模板库功能
在开发问卷分析功能时,我实现了一个高效的统计SQL:
sql复制SELECT
q.id AS question_id,
q.content,
COUNT(DISTINCT a.answer_sheet_id) AS answer_count,
GROUP_CONCAT(DISTINCT o.content) AS option_contents
FROM
question q
LEFT JOIN
answer a ON q.id = a.question_id
LEFT JOIN
`option` o ON q.id = o.question_id
WHERE
q.questionnaire_id = #{questionnaireId}
GROUP BY
q.id
这个项目从技术角度看不算复杂,但涵盖了SSM开发的各个环节。我在实际开发中最大的体会是:前期良好的数据库设计和规范的异常处理能节省大量后期调试时间。特别是对于问卷这种业务变化频繁的系统,采用纵表存储答案虽然查询稍复杂,但极大提高了扩展性。
