在高校社团管理日益数字化的背景下,一个高效、集中的信息管理平台显得尤为重要。传统乒乓球社团管理通常依赖微信群、Excel表格等分散工具,导致信息更新不及时、成员参与度低、活动组织效率低下。为此,我们设计并实现了一套基于SSM(Spring+SpringMVC+MyBatis)框架的乒乓球社团智能管理平台,旨在通过技术手段解决这些痛点,提升社团运营的专业化和系统化水平。
系统架构与技术栈
该平台采用经典的三层架构模式,严格遵循MVC设计原则,确保各层职责清晰、耦合度低。
技术栈组成:
- 后端框架:Spring 5.x(控制反转与事务管理)+ SpringMVC(Web请求分发)+ MyBatis 3.x(数据持久化)
- 前端技术:JSP(页面渲染)+ JavaScript/jQuery(交互逻辑)+ HTML5/CSS3(页面样式)
- 项目管理:Maven(依赖管理与构建)
- 数据库:MySQL 8.0(数据存储)
- 服务器:Tomcat 9.x(应用部署)
<!-- Maven核心依赖示例 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
</dependencies>
架构流程说明:
- 用户请求通过SpringMVC的DispatcherServlet进行统一接收和路由分发
- Controller层解析参数并调用Service层的业务逻辑方法
- Service层通过Spring的声明式事务管理确保数据一致性
- DAO层使用MyBatis的SQL映射执行数据库操作
- 查询结果通过JSP视图技术渲染后返回给前端用户
数据库设计亮点
平台共设计18张数据表,涵盖了用户管理、活动信息、订单处理等核心业务模块。以下重点分析几个关键表的设计亮点。
活动信息表(huodongxinxi)的设计优化
CREATE TABLE `huodongxinxi` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`huodongbianhao` varchar(50) NOT NULL COMMENT '活动编号',
`huodongmingcheng` varchar(255) NOT NULL COMMENT '活动名称',
`fenlei` int(10) unsigned NOT NULL COMMENT '分类',
`huodongtupian` text NOT NULL COMMENT '活动图片',
`xiaoshoujiage` decimal(18,2) NOT NULL COMMENT '销售价格',
`kucun` int(11) NOT NULL COMMENT '库存',
`zuozhe` varchar(50) NOT NULL COMMENT '作者',
`chubanshe` varchar(50) NOT NULL COMMENT '出版社',
`huodongxiangqing` longtext NOT NULL COMMENT '活动详情',
`tianjiaren` varchar(50) NOT NULL COMMENT '添加人',
`addtime` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '添加时间',
PRIMARY KEY (`id`),
KEY `huodongxinxi_fenlei_index` (`fenlei`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='活动信息'
设计亮点分析:
- 字段类型精准选择:
xiaoshoujiage使用decimal(18,2)确保金额计算的精确性;huodongxiangqing使用LONGTEXT类型支持富文本内容存储 - 索引优化:为
fenlei字段建立索引,显著提升按分类查询活动信息的性能 - 业务逻辑完整性:包含库存控制(
kucun)、添加人追踪(tianjiaren)、时间戳(addtime)等字段,满足完整业务流程需求
订单信息表(dingdanxinxi)的事务安全设计
CREATE TABLE `dingdanxinxi` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dingdanbianhao` varchar(50) NOT NULL COMMENT '订单编号',
`dingdanxinxi` text NOT NULL COMMENT '订单信息',
`zongjijine` decimal(18,2) NOT NULL COMMENT '总计金额',
`shouhuoren` varchar(50) NOT NULL COMMENT '收货人',
`dianhua` varchar(50) NOT NULL COMMENT '电话',
`dizhi` varchar(255) NOT NULL COMMENT '地址',
`beizhu` text NOT NULL COMMENT '备注',
`zhuangtai` varchar(255) NOT NULL COMMENT '状态',
`xiadanren` varchar(50) NOT NULL COMMENT '下单人',
`iszf` varchar(10) NOT NULL DEFAULT '否' COMMENT '是否支付',
`addtime` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '添加时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单信息'
事务安全保障:
- 订单编号(
dingdanbianhao)唯一性约束防止重复下单 - 支付状态(
iszf)与订单状态(zhuangtai)分离,支持灵活的订单流程管理 - 所有金额字段统一使用decimal类型,避免浮点数精度问题

核心功能实现
1. 用户身份认证与权限控制
平台采用基于Session的认证机制,通过自定义拦截器实现细粒度的权限控制。
/**
* 登录验证拦截器
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Users user = (Users) session.getAttribute("user");
if (user == null) {
// 未登录用户重定向到登录页面
response.sendRedirect(request.getContextPath() + "/login.do");
return false;
}
// 检查用户权限
String requestURI = request.getRequestURI();
if (!hasPermission(user, requestURI)) {
response.sendError(403, "权限不足");
return false;
}
return true;
}
private boolean hasPermission(Users user, String uri) {
// 根据用户角色和请求URI判断权限
// 实现细节...
return true;
}
}
SpringMVC配置:
<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/admin/**"/>
<bean class="com.spring.interceptor.AdminInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/**"/>
<bean class="com.spring.interceptor.UserInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

2. 活动信息管理模块
活动管理是平台的核心功能,支持活动的CRUD操作、分类管理和库存控制。
Service层业务逻辑实现:
@Service
public class HuodongxinxiService {
@Autowired
private HuodongxinxiMapper huodongxinxiMapper;
/**
* 添加活动信息(包含事务管理)
*/
@Transactional
public void addHuodongxinxi(Huodongxinxi huodongxinxi) {
// 生成活动编号
String huodongbianhao = generateBianhao();
huodongxinxi.setHuodongbianhao(huodongbianhao);
// 验证库存数量
if (huodongxinxi.getKucun() < 0) {
throw new RuntimeException("库存数量不能为负数");
}
// 插入数据库
int result = huodongxinxiMapper.insert(huodongxinxi);
if (result <= 0) {
throw new RuntimeException("添加活动信息失败");
}
}
/**
* 分页查询活动信息
*/
public PageInfo<Huodongxinxi> getHuodongxinxiList(int page, int size, String keyword) {
PageHelper.startPage(page, size);
Example example = new Example(Huodongxinxi.class);
if (StringUtils.isNotBlank(keyword)) {
example.createCriteria().andLike("huodongmingcheng", "%" + keyword + "%");
}
example.orderBy("addtime").desc();
List<Huodongxinxi> list = huodongxinxiMapper.selectByExample(example);
return new PageInfo<>(list);
}
private String generateBianhao() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
return "HD" + sdf.format(new Date()) +
String.format("%04d", (int)(Math.random() * 10000));
}
}
MyBatis映射文件示例:
<!-- HuodongxinxiMapper.xml -->
<mapper namespace="com.spring.mapper.HuodongxinxiMapper">
<resultMap id="BaseResultMap" type="com.spring.entity.Huodongxinxi">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="huodongbianhao" property="huodongbianhao" jdbcType="VARCHAR"/>
<result column="huodongmingcheng" property="huodongmingcheng" jdbcType="VARCHAR"/>
<result column="fenlei" property="fenlei" jdbcType="INTEGER"/>
<result column="xiaoshoujiage" property="xiaoshoujiage" jdbcType="DECIMAL"/>
<result column="kucun" property="kucun" jdbcType="INTEGER"/>
<result column="addtime" property="addtime" jdbcType="TIMESTAMP"/>
</resultMap>
<select id="selectByFenlei" parameterType="int" resultMap="BaseResultMap">
SELECT * FROM huodongxinxi
WHERE fenlei = #{fenlei} AND kucun > 0
ORDER BY addtime DESC
</select>
<update id="updateKucun">
UPDATE huodongxinxi
SET kucun = kucun - #{quantity}
WHERE id = #{id} AND kucun >= #{quantity}
</update>
</mapper>

3. 购物车与订单处理系统
平台实现了完整的电商式购物流程,包括购物车管理、订单生成和状态跟踪。
购物车Controller实现:
@Controller
@RequestMapping("/gouwuche")
public class GouwucheController extends BaseController {
@Autowired
private GouwucheService gouwucheService;
@Autowired
private HuodongxinxiService huodongxinxiService;
/**
* 添加商品到购物车
*/
@RequestMapping("/add")
@ResponseBody
public Map<String, Object> addToCart(HttpServletRequest request) {
Map<String, Object> result = new HashMap<>();
try {
Integer huodongxinxiid = Request.getInt("huodongxinxiid");
Integer goumaishuliang = Request.getInt("goumaishuliang");
// 获取当前登录用户
Users user = (Users) request.getSession().getAttribute("user");
if (user == null) {
result.put("success", false);
result.put("msg", "请先登录");
return result;
}
// 验证库存
Huodongxinxi huodongxinxi = huodongxinxiService.find(huodongxinxiid);
if (huodongxinxi.getKucun() < goumaishuliang) {
result.put("success", false);
result.put("msg", "库存不足");
return result;
}
// 添加到购物车
Gouwuche gouwuche = new Gouwuche();
gouwuche.setHuodongxinxiid(huodongxinxiid);
gouwuche.setGoumaishuliang(goumaishuliang);
gouwuche.setGoumairen(user.getUsername());
gouwuche.setXiaoji(huodongxinxi.getXiaoshoujiage().multiply(
new BigDecimal(goumaishuliang)));
gouwucheService.insert(gouwuche);
result.put("success", true);
result.put("msg", "添加成功");
} catch (Exception e) {
result.put("success", false);
result.put("msg", "系统错误:" + e.getMessage());
}
return result;
}
}
订单生成Service:
@Service
public class DingdanxinxiService {
@Autowired
private DingdanxinxiMapper dingdanxinxiMapper;
@Autowired
private GouwucheService gouwucheService;
@Autowired
private HuodongxinxiService huodongxinxiService;
/**
* 生成订单(事务管理)
*/
@Transactional
public String createOrder(List<Integer> cartIds, Users user, String address) {
// 生成订单编号
String dingdanbianhao = generateOrderNumber();
// 计算总金额并验证库存
BigDecimal zongjijine = BigDecimal.ZERO;
StringBuilder dingdanxinxi = new StringBuilder();
for (Integer cartId : cartIds) {
Gouwuche cartItem = gouwucheService.find(cartId);
Huodongxinxi huodongxinxi = huodongxinxiService.find(
cartItem.getHuodongxinxiid());
// 库存验证
if (huodongxinxi.getKucun() < cartItem.getGoumaishuliang()) {
throw new RuntimeException(huodongxinxi.getHuodongmingcheng() + "库存不足");
}
// 更新库存
huodongxinxiService.updateKucun(huodongxinxi.getId(),
cartItem.getGoumaishuliang());
BigDecimal xiaoji = huodongxinxi.getXiaoshoujiage()
.multiply(new BigDecimal(cartItem.getGoumaishuliang()));
zongjijine = zongjijine.add(xiaoji);
dingdanxinxi.append(huodongxinxi.getHuodongmingcheng())
.append(" × ").append(cartItem.getGoumaishuliang())
.append(" = ").append(xiaoji).append("元\n");
}
// 创建订单
Dingdanxinxi order = new Dingdanxinxi();
order.setDingdanbianhao(dingdanbianhao);
order.setDingdanxinxi(dingdanxinxi.toString());
order.setZongjijine(zongjijine);
order.setShouhuoren(user.getUsername());
order.setDizhi(address);
order.setXiadanren(user.getUsername());
order.setZhuangtai("待支付");
dingdanxinxiMapper.insert(order);
// 清空购物车
for (Integer cartId : cartIds) {
gouwucheService.delete(cartId);
}
return dingdanbianhao;
}
}

4. 后台管理系统
后台管理模块采用RBAC(基于角色的访问控制)模型,支持多级管理员权限分配。
管理员Controller核心代码:
@Controller
@RequestMapping("/admin")
public class AdminController extends BaseController {
@Autowired
private AdminsService adminsService;
/**
* 管理员列表分页查询
*/
@RequestMapping("/list")
public String list(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size,
String keyword, Model model) {
Example example = new Example(Admins.class);
if (StringUtils.isNotBlank(keyword)) {
example.createCriteria().andLike("username", "%" + keyword + "%");
}
example.orderBy("addtime").desc();
PageHelper.startPage(page, size);
List<Admins> adminList = adminsService.selectByExample(example);
PageInfo<Admins> pageInfo = new PageInfo<>(adminList);
model.addAttribute("list", adminList);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("keyword", keyword);
return "admin/list";
}
/**
* 添加管理员(权限验证)
*/
@RequestMapping("/add")
@ResponseBody
public Map<String, Object> addAdmin(Admins admin, HttpSession session) {
Map<String, Object> result = new HashMap<>();
// 权限验证
Admins currentAdmin = (Admins) session.getAttribute("admin");
if (!"superadmin".equals(currentAdmin.getQuanxian())) {
result.put("success", false);
result.put("msg", "权限不足");
return result;
}
// 用户名重复检查
Example checkExample = new Example(Admins.class);
checkExample.createCriteria().andEqualTo("username", admin.getUsername());
if (adminsService.selectCountByExample(checkExample) > 0) {
result.put("success", false);
result.put("msg", "用户名已存在");
return result;
}
// 密码加密