1. SSM高校普法系统项目概述
这个基于SSM框架的高校普法系统,是我去年为某政法大学开发的一套校园普法教育管理平台。系统采用经典的Spring+SpringMVC+MyBatis技术栈,主要解决高校普法教育中存在的三个痛点:普法活动管理分散、师生参与度低、教育效果难以量化评估。
系统包含前台普法门户和后台管理两大模块。前台面向师生提供普法课程学习、在线考试、案例库查询等功能;后台则包含用户管理、活动发布、数据统计等管理功能。整个项目从零开始搭建,经历了技术选型、环境配置、数据库设计、功能开发、测试部署等完整生命周期。
提示:SSM框架组合在JavaWeb开发中非常常见,但实际开发时Spring和MyBatis的版本兼容性问题经常导致项目启动失败,建议在环境搭建阶段就固定版本组合。
2. 开发环境搭建与配置
2.1 基础环境准备
我选择的是Java 1.8 + Tomcat 8.5 + Maven 3.6的组合,这是经过多个项目验证的稳定搭配。具体安装步骤:
- JDK配置需特别注意环境变量:
bash复制# 在~/.bash_profile中添加
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
- Maven的settings.xml需要配置阿里云镜像:
xml复制<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
2.2 IDE选择与插件
使用IntelliJ IDEA作为主开发工具,必须安装的插件包括:
- Lombok(减少样板代码)
- MyBatisX(Mapper接口与XML跳转)
- Alibaba Java Coding Guidelines(代码规范检查)
2.3 数据库环境
MySQL 5.7版本,字符集必须设置为utf8mb4以支持完整Unicode字符:
sql复制CREATE DATABASE `law_edu` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3. 项目架构设计与技术选型
3.1 SSM框架整合
采用分层架构设计:
code复制law-edu
├── law-common -- 通用工具包
├── law-dao -- 数据持久层
├── law-service -- 业务逻辑层
├── law-web -- 控制层
└── law-pojo -- 实体类
Spring配置的关键点:
xml复制<!-- 开启注解驱动 -->
<context:component-scan base-package="com.law.edu"/>
<mvc:annotation-driven/>
<!-- MyBatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
3.2 前端技术栈
虽然项目主体是SSM,但前端采用了:
- AdminLTE后台模板(基于Bootstrap)
- ECharts数据可视化
- WangEditor富文本编辑器
- Layer弹层组件
这种组合既保证了开发效率,又能满足管理系统的UI需求。
4. 数据库设计与实现
4.1 核心表结构
系统包含28张表,关键表设计如下:
- 用户表(sys_user):
sql复制CREATE TABLE `sys_user` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '登录名',
`password` varchar(100) NOT NULL COMMENT '密码',
`salt` varchar(20) DEFAULT NULL COMMENT '盐',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`mobile` varchar(100) DEFAULT NULL COMMENT '手机号',
`status` tinyint(4) DEFAULT NULL COMMENT '状态 0:禁用 1:正常',
`college_id` bigint(20) DEFAULT NULL COMMENT '学院ID',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户';
- 普法课程表(law_course):
sql复制CREATE TABLE `law_course` (
`course_id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL COMMENT '课程标题',
`cover_url` varchar(255) DEFAULT NULL COMMENT '封面图URL',
`video_url` varchar(255) DEFAULT NULL COMMENT '视频URL',
`content` text COMMENT '课程内容',
`view_count` int(11) DEFAULT '0' COMMENT '浏览次数',
`status` tinyint(4) DEFAULT '0' COMMENT '状态:0-未发布 1-已发布',
`create_user_id` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普法课程表';
4.2 MyBatis优化实践
- 使用MyBatis Generator自动生成基础CRUD代码:
xml复制<!-- generatorConfig.xml配置示例 -->
<table tableName="sys_user" domainObjectName="SysUser"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<generatedKey column="user_id" sqlStatement="MySql" identity="true"/>
</table>
- 自定义TypeHandler处理枚举类型:
java复制public class LawTypeHandler extends BaseTypeHandler<LawType> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
LawType parameter, JdbcType jdbcType) {
ps.setInt(i, parameter.getCode());
}
//...其他方法实现
}
5. 核心功能实现细节
5.1 普法课程管理模块
课程发布流程的关键代码:
java复制@Controller
@RequestMapping("/admin/course")
public class CourseController {
@Autowired
private CourseService courseService;
@PostMapping("/save")
@ResponseBody
public R save(@Valid Course course, MultipartFile coverFile) {
if(coverFile != null && !coverFile.isEmpty()){
String fileName = FileUploadUtil.upload(coverFile);
course.setCoverUrl(fileName);
}
courseService.saveCourse(course);
return R.ok();
}
@GetMapping("/info/{courseId}")
public String info(@PathVariable("courseId") Long courseId, Model model) {
CourseVO course = courseService.getCourseDetail(courseId);
model.addAttribute("course", course);
return "admin/course/courseInfo";
}
}
5.2 在线考试系统实现
考试模块采用Redis缓存试题,防止频繁查询数据库:
java复制@Service
public class ExamServiceImpl implements ExamService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String EXAM_PREFIX = "exam:";
@Override
public List<Question> getRandomQuestions(Integer type, Integer count) {
String key = EXAM_PREFIX + type;
List<Question> questions = (List<Question>) redisTemplate.opsForValue().get(key);
if(CollectionUtils.isEmpty(questions)){
questions = questionMapper.selectByType(type);
redisTemplate.opsForValue().set(key, questions, 2, TimeUnit.HOURS);
}
return questions.stream()
.sorted((o1, o2) -> Math.random() > 0.5 ? 1 : -1)
.limit(count)
.collect(Collectors.toList());
}
}
6. 系统部署与运维
6.1 生产环境部署
采用Nginx+Tomcat集群部署方案:
code复制server {
listen 80;
server_name law.edu.com;
location / {
proxy_pass http://tomcat_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
root /data/static;
expires 30d;
}
}
upstream tomcat_cluster {
server 192.168.1.101:8080 weight=1;
server 192.168.1.102:8080 weight=1;
keepalive 32;
}
6.2 常见问题排查
- 中文乱码问题解决方案:
- 确保MySQL连接字符串包含characterEncoding=utf8
- Tomcat的server.xml中Connector添加URIEncoding="UTF-8"
- 所有JSP页面添加<%@ page contentType="text/html;charset=UTF-8"%>
- MyBatis查询结果映射失败:
- 检查实体类字段名与数据库是否一致(包括大小写)
- 确认resultMap配置是否正确
- 使用@Results注解时注意column和property的对应关系
7. 项目优化经验分享
7.1 性能优化实践
- 使用Druid连接池并配置监控:
properties复制# application.properties配置
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.web-stat-filter.enabled=true
- 添加二级缓存提升查询性能:
java复制@CacheConfig(cacheNames = "course")
@Service
public class CourseServiceImpl implements CourseService {
@Cacheable(key = "#courseId")
@Override
public CourseVO getCourseDetail(Long courseId) {
//...查询逻辑
}
@CacheEvict(allEntries = true)
@Override
public void clearCache() {
// 清空缓存
}
}
7.2 安全防护措施
- 密码加密存储:
java复制public class PasswordUtil {
private static final String ALGORITHM_NAME = "MD5";
private static final int HASH_ITERATIONS = 5;
public static String encrypt(String password, String salt) {
return new SimpleHash(ALGORITHM_NAME, password,
ByteSource.Util.bytes(salt), HASH_ITERATIONS).toHex();
}
}
- XSS防护:
java复制@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean<XssFilter> xssFilter() {
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new XssFilter());
registration.addUrlPatterns("/*");
registration.setName("xssFilter");
return registration;
}
}
这个项目从零开始到最终上线历时3个月,期间遇到了不少技术挑战,特别是SSM版本兼容性和高并发场景下的性能问题。通过合理的架构设计和持续优化,最终系统支持了全校2万多名师生的普法学习需求,日活最高达到3000人次。对于想学习SSM完整开发流程的开发者,这个项目提供了很好的实践参考。
