news 2026/4/23 10:56:40

基于Spring、Mybatis、Spring MVC的留言本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Spring、Mybatis、Spring MVC的留言本

实验名称

基于Spring、Mybatis、Spring MVC的留言本

实验目的和要求 :

目的:熟练掌握Spring、Mybatis、Spring MVC框架基本用法。

要求:实现简单留言本的发贴和回复功能,效果图如下:

实验实现思路及步骤:

一、核心实现思路

以 SSM(Spring、Spring MVC、MyBatis)框架为技术核心,遵循 MVC 分层架构设计留言本系统。其中,Spring 负责管理 Service 层 Bean 的创建与依赖注入,并提供事务管理保障数据操作一致性;Spring MVC 承担请求处理与视图跳转,通过 Controller 接收前端请求、调用 Service 层逻辑,再将数据传递到视图层渲染;MyBatis 简化数据持久化,借助 Mapper 接口与 XML 映射文件实现留言查询、新增、回复更新,避免硬编码 SQL。整体流程为前端发起请求→Spring MVC 拦截并分发到对应 Controller→Controller 调用 Service 处理业务→Service 调用 Dao 层操作数据库→数据通过 JSP 视图展示,最终实现发布留言、列表展示、管理员回复的完整功能。

二、具体实施步骤

环境搭建与依赖配置:在 IntelliJ IDEA 中创建 Maven Web 项目,设置项目标识;在 pom.xml 中引入 SSM 框架核心依赖、MySQL 驱动、数据库连接池(Druid)、JSP 相关依赖等;配置 Tomcat 9.0 服务器,将项目部署并设置端口与上下文路径。

框架配置文件编写:编写 Spring 配置文件(applicationContext.xml),配置 Service 层扫描、Druid 数据源、MyBatis SqlSessionFactory、Mapper 接口扫描及事务管理;编写 Spring MVC 配置文件(spring-mvc.xml),配置 Controller 层扫描、视图解析器(指定 JSP 路径与后缀)及静态资源放行;编写 MyBatis 配置文件(mybatis-config.xml),配置日志(Log4j)与实体类别名;编写 web.xml,配置 Spring 监听器、Spring MVC 前端控制器(DispatcherServlet)及字符编码过滤器解决中文乱码。

数据库设计与创建:创建 message_db 数据库,在库中新建 message 表,表包含 id(主键自增)、username(留言人)、content(留言内容)、create_time(留言时间,默认当前时间)、reply(回复内容)、reply_time(回复时间)字段;通过 MySQL 客户端执行 SQL 语句完成数据库与表的创建。

分层代码开发:

实体层:创建 Message 类,对应 message 表字段,生成无参、有参构造及 getter/setter 方法。

Dao 层:编写 MessageMapper 接口,定义查询所有留言(按创建时间倒序)、新增留言、更新回复的方法;编写对应的 Mapper XML 映射文件,实现接口方法的 SQL 逻辑。

Service 层:编写 MessageService 接口,定义获取留言列表、发布留言、回复留言的业务方法;编写 Service 实现类,注入 MessageMapper,调用 Dao 层方法处理业务,添加 @Transactional 注解保障事务。

Controller 层:创建 MessageController,添加 @RequestMapping 指定类级请求前缀;编写方法分别处理跳转留言列表页(获取留言数据存入 Model 并返回视图名)、跳转发布留言页(直接返回视图名)、处理发布留言请求(接收表单参数调用 Service,重定向到列表页)、处理回复请求(接收留言 ID 与回复内容调用 Service,重定向到列表页)。

视图层:编写留言列表 JSP(messageList.jsp),用 JSTL 遍历留言数据展示留言人、时间、内容,显示已有回复,提供回复表单与发布留言链接;编写发布留言 JSP(publishMessage.jsp),设计表单收集留言人姓名与内容,提供发布与取消按钮。

系统测试与运行:启动 MySQL 服务与 Tomcat 服务器,查看控制台确认无报错;访问留言列表页验证初始状态;点击发布留言输入信息提交,验证留言新增与页面重定向;在回复表单输入内容提交,验证回复显示;通过 MySQL 客户端查询 message 表,确认数据存储正确。

主要开发工具

IntelliJ IDEA2025.1.3,MySQL 8.0,Navicat

实验效果及主要实现代码:

一、实验效果说明

1. 整体页面布局与视觉呈现

顶部导航栏:固定在页面顶部(sticky top-0),左侧显示系统名称 “SSM 留言本” 与留言图标(fa fa-comments),右侧包含 “欢迎访问” 提示文本与 “刷新” 按钮。导航栏采用白色背景 + 阴影效果,点击 “刷新” 按钮时会触发页面数据重新加载,同时显示 “页面已刷新” 的 Toast 提示(底部右侧弹出,3 秒后自动消失),提升用户操作反馈感。


核心功能区:采用响应式布局,在 PC 端(lg:flex)分为左右两栏,移动端自动堆叠为纵向排列。左侧占 1/3 宽度,为 “发表新留言” 功能区;右侧占 2/3 宽度,为 “留言列表 + 筛选控制” 功能区,两栏均使用白色卡片式设计(bg-white rounded-lg shadow-card),hover 时阴影加深(shadow-card-hover),增强视觉交互,如图1-1。

图1-1 整体效果

2. 核心功能交互效果

(1)发表新留言功能

表单设计:左侧发帖区包含 “标题”(必填)、“用户名”(必填)、“内容”(必填)三个输入项,其中 “内容” 使用多行文本框(rows="4")。提交按钮为蓝色主色调(bg-primary),hover 时变为深蓝色(bg-blue-600),并带有图标(fa fa-paper-plane),增强操作引导。如图1-2。

图1-2 发表新留言

交互逻辑:

未填写必填项时,浏览器原生校验(required)会提示 “请填写此字段”,避免空数据提交;

填写完成后点击 “发布”,通过 AJAX 异步提交数据(无页面刷新),提交过程中按钮禁用(防止重复提交);

提交成功后:① 表单自动清空;② 留言列表实时刷新,新留言置顶显示,如图1-3。


图1-3 刷新新留言

(2)留言列表展示功能

数据展示格式:每条留言以独立卡片呈现,包含 3 个核心区域:

留言头部:浅蓝色背景(bg-primary bg-opacity-10),左侧显示留言标题(加粗,font-semibold),右侧显示发布时间(浅灰色小字体,text-xs text-gray-dark);

留言内容:白色背景,显示留言正文(text-gray-dark),自动换行适配内容长度;

留言底部:浅灰色背景(bg-gray-light),左侧显示回复数量(如 “回复 (2)”),右侧显示 “回复” 按钮(蓝色文本,hover 时加深);

回复列表:每条留言下方嵌套显示关联的回复,回复项采用浅灰色边框分隔,显示回复内容与回复时间(text-sm字体),无回复时不显示空白区域,避免视觉冗余。

用户提交回复后,模态框自动关闭,列表实时刷新显示新回复,同时弹出操作提示,互动流程顺畅,如图1-4

图1-4 回复留言
点击留言底部的 "回复" 按钮,会弹出一个模态框(半透明背景,居中显示),模态框顶部显示 "回复留言" 标题,中间区域显示被回复留言的标题和内容(灰色背景),下方是 "回复内容" 文本框(必填),底部有 "取消" 和 "回复" 按钮。填写回复内容后点击 "回复",前端验证通过后发送请求到后端,成功后关闭模态框,刷新列表显示新回复,并弹出提示如图1-5。

图1-5 刷新回复页面

(3)排序与搜索功能

排序交互:右侧留言列表顶部包含 “排序下拉框”,提供 “最新发布”(默认)与 “最早发布” 两个选项。选择排序方式后,无需页面刷新,留言列表会实时按所选规则重新排列(最新发布按createTime降序,最早发布按createTime升序),排序过程中无加载等待提示(因数据量小,响应速度 < 300ms)。

搜索交互:排序下拉框右侧为 “搜索输入框”(带fa fa-search图标),输入关键词(支持标题、留言内容、回复内容匹配)时,实时筛选留言列表,如图1-6

图1-6 搜索留言

二、核心代码实现

1. 实体层代码

// Message实体类

public class Message {

private Integer id;

private String title;

private String username;

private String content;

private Date createTime;

private List<Reply> replies;

// 无参/有参构造、getter/setter方法

}

关键说明:

配合 MyBatis 的mapUnderscoreToCamelCase配置(需在mybatis-config.xml中设置),可自动完成字段映射,无需手动编写resultMap;

List<Reply> replies是核心关联字段:因实验需实现 “留言 - 回复” 功能,1 条留言可对应多条回复,用List存储关联的回复数据,为 Service 层 “查询留言时同步查回复” 提供数据结构;

无参构造、getter/setter 是 MyBatis 反射赋值的必要条件(MyBatis 通过反射创建对象并设置字段值)。

// Reply实体类

public class Reply {

private Integer id;

private Integer messageId;

private String content;

private Date createTime;

// 无参/有参构造、getter/setter方法

}

关键说明:

messageId是外键字段:通过该字段与message表的id关联,确保每条回复能对应到具体留言,是 “查询留言时同步查回复” 的关联依据;

字段设计极简:仅保留回复功能必需的核心信息,符合实验 “简单留言本” 的需求,避免冗余字段增加开发复杂度。

2. Dao 层代码(MessageMapper.java)

public interface MessageMapper {

List<Message> selectAllMessages(@Param("sort") String sort);

int insertMessage(Message message);

List<Message> searchMessages(@Param("keyword") String keyword);

}

关键说明:

接口设计原则:每个方法对应一个具体的数据库操作,方法名与业务语义一致(如selectAllMessages即 “查询所有留言”),便于后续 Service 层调用;

@Param("sort")注解:用于传递单个参数时指定参数名,确保 MyBatis 在 XML 映射文件中能通过#{sort}正确获取参数值(如sort为 “newest” 时按时间降序,“oldest” 时升序);

返回值设计:

List<Message>:查询操作返回多条留言数据,符合 “留言列表展示” 功能需求;

int:新增操作返回 “受影响的行数”(MySQL 中新增 1 条数据成功时返回 1,失败返回 0),用于判断新增是否成功;

无实现类原因:MyBatis 会在运行时通过 “动态代理” 自动生成接口的实现类,核心逻辑在对应的 XML 映射文件(如MessageMapper.xml)中通过 SQL 语句定义,减少重复代码。

3. Service 层代码(MessageServiceImpl.java)

@Service

@Transactional

public class MessageServiceImpl implements MessageService {

@Autowired

private MessageMapper messageMapper;

@Autowired

private ReplyMapper replyMapper;

@Override

public List<Message> getAllMessages(String sort) {

List<Message> messages = messageMapper.selectAllMessages(sort);

messages.forEach(msg -> {

List<Reply> replies = replyMapper.selectByMessageId(msg.getId());

msg.setReplies(replies);

});

return messages;

}

@Override

public int addMessage(Message message) {

message.setCreateTime(new Date());

return messageMapper.insertMessage(message);

}

}

关键说明:

@Service注解:将类标识为 “业务层 Bean”,Spring 启动时会扫描该类并创建实例存入 IOC 容器,后续 Controller 层可通过@Autowired直接注入使用(解耦 “业务逻辑” 与 “请求处理”);

@Autowired注解:实现 “依赖注入”(Spring 核心特性),自动从 IOC 容器中获取MessageMapper和ReplyMapper的实例,无需手动创建,避免代码耦合(如无需写messageMapper = new MessageMapperImpl());

@Transactional注解:实验中 “新增留言” 是简单操作,但若后续扩展 “新增留言后同步记录日志” 等多步数据库操作,该注解可确保所有操作要么同时成功,要么同时失败(如日志插入失败时,留言新增也回滚),保障数据一致性;

业务逻辑封装:getAllMessages中 “循环查回复” 的逻辑封装在 Service 层,Controller 层调用时无需关注 “如何关联回复”,只需直接获取完整数据,符合 “单一职责原则”(Controller 只处理请求,Service 只处理业务)。

4. Controller 层代码(MessageController.java)

@Controller

@RequestMapping("/message")

public class MessageController {

@Autowired

private MessageService messageService;

@RequestMapping("/list")

@ResponseBody

public List<Message> getMessageList(@RequestParam String sort) {

return messageService.getAllMessages(sort);

}

@RequestMapping("/add")

@ResponseBody

public Map<String, Object> addMessage(Message message) {

Map<String, Object> result = new HashMap<>();

int row = messageService.addMessage(message);

result.put("success", row > 0);

return result;

}

}

关键说明:

@Controller与@RequestMapping:@Controller标识类为请求处理器,@RequestMapping("/message")定义统一路径前缀,避免不同 Controller 的路径冲突(如其他功能的路径可前缀/user);

@ResponseBody注解:实验中前端通过 AJAX 异步请求后端,需要 JSON 格式的响应数据(而非跳转页面),该注解会自动将 Java 对象(List<Message>或Map)转为 JSON,无需手动处理格式转换;

@RequestParam String sort:接收前端传递的sort参数(如前端请求/message/list?sort=newest),若前端未传该参数会报错,确保请求参数完整性;

Message message参数:Spring MVC 自动将前端提交的表单参数(如title=测试&username=张三)封装为Message对象,参数名与Message字段名一致即可自动匹配(如title对应message.setTitle()),简化参数接收代码;

Map返回结果:前端需要知道 “新增是否成功”,用Map存储success键(布尔值),前端可通过data.success直接判断(如if(data.success){提示成功}),符合前后端交互的通用逻辑。

5. 前端 AJAX 交互代码

// 发布留言提交

postForm.addEventListener('submit', function(e) {

e.preventDefault();

const title = document.getElementById('postTitle').value;

const username = document.getElementById('postUsername').value;

const content = document.getElementById('postContent').value;

fetch('/message/add', {

method: 'POST',

headers: {'Content-Type': 'application/x-www-form-urlencoded'},

body: `title=${encodeURIComponent(title)}&username=${encodeURIComponent(username)}&content=${encodeURIComponent(content)}`

})

.then(res => res.json())

.then(data => {

if (data.success) {

postForm.reset();

handleRefresh();

showToast('留言发布成功!');

}

});

});

e.preventDefault():表单默认提交会刷新页面,破坏 “无刷新交互” 的体验,该方法阻止默认行为,确保 AJAX 异步提交;

请求路径/message/add:必须与 Controller 层MessageController的@RequestMapping("/message")+@RequestMapping("/add")完全一致,否则后端无法接收请求;

method: 'POST':新增操作需修改数据库数据,用 POST 请求更安全(GET 请求参数会暴露在 URL 中),与后端 Controller 的请求方式适配;

Content-Type: application/x-www-form-urlencoded:告知后端 “请求体是表单参数格式”,与 Controller 中 “Message message接收参数” 的方式匹配,确保后端能正确解析参数;

encodeURIComponent():处理用户输入中的中文(如姓名 “张三”),避免中文在传输过程中出现乱码,后端 Spring MVC 会自动解码;

响应处理逻辑:

res.json():将后端返回的 JSON 字符串转为 JavaScript 对象(与@ResponseBody的 JSON 格式对应);

data.success:直接获取后端返回的success字段(来自 Controller 的Map),判断新增是否成功;

成功后的操作:reset()清空表单(方便用户继续发布)、handleRefresh()刷新留言列表(实时显示新留言)、showToast()提示成功(告知用户操作结果),形成完整的交互闭环。

遇到的问题和解决方法:

问题:前端 AJAX 提交数据后,后端无法接收中文参数。

解决方法:在 web.xml 配置 CharacterEncodingFilter,设置编码为 UTF-8,确保前后端编码一致。

问题:前端提交留言后,页面需要刷新才能显示新数据。

解决方法:使用 AJAX 异步提交表单,成功后通过 JavaScript 动态添加留言到页面顶部,无需整体刷新。

实验总结:

本次实验通过SSM框架完整实现了留言本的发帖、回复、排序、搜索等功能,深入掌握了三大框架的整合与应用。Spring的依赖注入简化了组件间的耦合,Spring MVC实现了请求的灵活分发与异步数据返回,MyBatis高效完成数据持久化操作,配合Tailwind CSS构建的前端页面,提升了系统的交互体验与视觉效果。实验中掌握了AJAX异步交互、MyBatis关联查询、事务管理等关键技能,同时发现对复杂查询优化和前端样式细节优化仍需加强。后续可扩展用户登录认证、留言删除编辑、图片上传等功能,进一步完善系统。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 10:53:47

5分钟快速上手:Blender终极PSK/PSA格式导入导出插件完整指南

5分钟快速上手&#xff1a;Blender终极PSK/PSA格式导入导出插件完整指南 【免费下载链接】io_scene_psk_psa A Blender extension for importing and exporting Unreal PSK and PSA files 项目地址: https://gitcode.com/gh_mirrors/io/io_scene_psk_psa Unreal PSK/PSA…

作者头像 李华
网站建设 2026/4/23 10:53:10

DS4Windows完整指南:3步让PlayStation手柄在Windows电脑上完美运行

DS4Windows完整指南&#xff1a;3步让PlayStation手柄在Windows电脑上完美运行 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 想要在Windows电脑上使用PlayStation手柄畅玩所有游戏吗&am…

作者头像 李华
网站建设 2026/4/23 10:47:16

Windows HEIC缩略图提供程序:深入解析系统级图像预览技术

Windows HEIC缩略图提供程序&#xff1a;深入解析系统级图像预览技术 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC/HEIF files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 超过80%的i…

作者头像 李华