ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SSM+Vue前后端分离个人事务管理系统开发实践解析

SSM+Vue前后端分离个人事务管理系统开发实践解析 简介这套基于SSM与Vue的个人事务管理系统源码附带毕业论文面向计算机、数学、电子信息等专业的毕业设计、课程设计及期末大作业场景是一份可直接参考学习的完整项目。后端采用Spring、SpringMVC、MyBatis分层架构前端用Vue.js配合ECMAScript编写动态交互页面MySQL存储业务数据功能覆盖个人日常事务的登记、删除、编辑、提醒、状态流转与分类统计等常见模块代码包内还包含数据库初始化脚本与接口联调所需配置。资源包为ZIP压缩共392个文件、约9.99MB其中79个Java文件负责业务处理36个Vue文件组成界面组件19个JS脚本辅助前后端交互16个XML配置完成框架整合另有CSS样式、SVG/PNG图标、SQL脚本及npm相关的运行打包脚本可帮助你快速搭建环境并启动项目。当前已有85人学习下载随包附带的毕业论文可用于理解系统需求分析、概要设计与功能实现借助安装、运行、打包批处理脚本几乎能一键完成本地部署。项目目录结构清晰代码可读性高无论是作为毕业设计样本还是作为SSMVue前后端分离技术的练手项目都具备较好的参考与二次开发价值。1. 个人事务管理系统SSM 与 Vue 的前后端分离落地个人事务管理系统这类选题几乎每年都出现在 Java 相关的毕业设计和课程作业里原因是它的业务边界足够清晰用户注册登录、待办事项的增删改查、日程提醒、分类统计每一块都能对应到 SSM 框架的核心知识点上。用 SSM 做后端接口、Vue 做前端页面正好覆盖了从数据库表设计到前后端联调的完整链路这也是为什么现成的源码包在求职和答辩场景里被反复检索。这套资源内置了 MySQL 数据库脚本、SSM 后端工程、Vue 前端工程和毕业论文文档Windows 环境下通过三个批处理文件1-install.bat、2-run.bat、3-build.bat就能把环境跑起来。对打算二次开发的人来说真正的门槛不在启动而在理解 SSM 的请求流转和 Vue 与后端的数据契约这两个问题捋清楚后面的改造就只是堆代码的事。2. SSM 后端分层从 Controller 到 Mapper 的事务处理链路2.1 SSM 三件套在项目里的实际分工SSM 是 Spring、Spring MVC、MyBatis 三个框架的组合它们各管一段Spring 负责对象创建和依赖注入Spring MVC 负责接收 HTTP 请求并分发到 ControllerMyBatis 负责把 Java 方法和 SQL 映射起来。在个人事务管理系统里一个典型的请求链路是Vue 前端发送POST /api/task/saveTomcat 把请求交给 DispatcherServlet再由 HandlerMapping 找到对应的 TaskControllerController 调用 TaskServiceService 通过 TaskMapper 接口执行 SQL最后把结果逐层返回。这种分层的直接好处是替换成本低。比如要换 ORM 层只动 Mapper 和 MyBatis 配置Controller 和 Service 不需要改要加一个统计功能只需要在 Service 里组合现有 Mapper 方法。2.2 spring-mvc.xml 中关键配置的取舍SSM 工程里spring-mvc.xml是请求路由的核心启动阶段容易出错的地方基本都集中在这里。下面的配置片段是这套资源常见的形态!-- 扫描 controller 包 -- context:component-scan base-packagecom.personal.controller/ !-- 开启 Spring MVC 注解驱动 -- mvc:annotation-driven/ !-- 静态资源放行避免 .js/.css 被拦截 -- mvc:resources mapping/static/** location/static// !-- 视图解析器 -- bean classorg.springframework.web.servlet.view.InternalResourceViewResolver property nameprefix value/WEB-INF/jsp// property namesuffix value.jsp/ /beancomponent-scan只扫描 controller 包这一点容易被忽略。如果扫描范围过大把 Service 也扫进来会出现事务注解不生效的怪问题因为 Spring 容器和 Spring MVC 容器各自管理了一部分 Bean代理对象不是同一个。mvc:annotation-driven负责注册 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter没有这行Controller 里的RequestMapping无法生效。提示如果项目里同时存在applicationContext.xml和spring-mvc.xml要确认 Service 和 Mapper 在根容器里扫描Controller 在 MVC 容器里扫描职责分开。2.3 Service 层的事务边界个人事务系统的核心操作是待办事项的保存和状态更新单表操作看起来不需要事务但实际使用中会有批量操作场景比如一次性勾选多条任务标记为已完成、把整天的日程复制到另一天。这时事务就很重要。spring-mybatis.xml里通常用DataSourceTransactionManager管理事务bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean tx:annotation-driven transaction-managertransactionManager/Service 实现类的方法上标注Transactional即可声明事务。需要注意readOnlytrue的使用范围只在纯粹的查询方法上设置否则 Spring 会做只读优化某些数据库方言下插入操作会报异常。事务默认只回滚运行时异常如果在 Service 里 catch 了异常而没有 rethrow事务不会触发回滚数据会停留在不一致的状态。2.4 MyBatis Mapper 的编写与参数传递MyBatis 的 Mapper 接口和 XML 映射文件是 SSM 项目里写 SQL 的主要位置。以任务查询为例public interface TaskMapper { ListTask selectTaskList(Param(userId) Integer userId, Param(status) Integer status); int insertTask(Task task); int updateTaskStatus(Param(id) Integer id, Param(status) Integer status, Param(updateTime) Date updateTime); int deleteTask(Integer id); }对应的TaskMapper.xmlselect idselectTaskList resultTypecom.personal.entity.Task SELECT id, user_id, title, content, status, due_time FROM t_task where if testuserId ! null AND user_id #{userId} /if if teststatus ! null AND status #{status} /if /where ORDER BY due_time ASC /select update idupdateTaskStatus UPDATE t_task SET status #{status}, update_time #{updateTime} WHERE id #{id} /updateParam注解用来显式指定参数名这比直接用#{0}、#{1}可读性好得多。有一个常见错误是方法只有一个参数时XML 里直接写#{id}没问题一旦参数变成两个编译器在 debug 模式下能拿到参数名release 模式下拿不到不加Param就是各种BindingException。个人事务系统里任务查询经常同时带 userId 和 status所以从一开始就养成了用Param的习惯。where标签会自动处理多余的 AND 或 OR多条件组合查询时不必在 SQL 尾部拼where 11这也是 MyBatis 相比 JDBC 手写 SQL 的优势。3. Vue 前端与 SSM 的联调路由、接口封装与跨域3.1 Vue 工程的目录结构与构建脚本这套资源的前端不是简单的 HTML 页面而是完整的 Vue 工程.vue单文件组件、vue-router、axios一应俱全。资源里保留了update-password.vue.bak、IndexAsideStatic.vue.bak这类备份文件是开发过程中用 git 或编辑器历史功能没有清干净的残留。拿到项目第一件事应该是先跑1-install.batcall npm install call npm run dev1-install.bat实际就是npm install2-run.bat是启动后端通常是启动 Tomcat 或执行 Spring Boot 的 jar3-build.bat是前端生产构建npm run build。如果npm install卡在某个依赖上检查 Node 版本Vue 2 项目在 Node 18 以上环境容易报 OpenSSL 错误解决办法是set NODE_OPTIONS--openssl-legacy-provider再执行。3.2 vue.config.js 的代理与跨域处理SSM 后端默认跑在 8080 端口Vue 开发服务器跑在 8081 或 9090浏览器直接访问后端接口会触发跨域。项目里常用的方案不是在后端加 CORS 过滤器而是在vue.config.js里配置 devServer 代理module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: } } } } }所有以/api开头的请求都会被转发到http://localhost:8080pathRewrite把/api前缀去掉。后端 Controller 的 RequestMapping 里不需要带/api两边互不干扰。注意changeOrigin: true是给后端发请求时把 Host 头改成 target 的域名一些后端框架会校验 Host不改可能报 403。3.3 axios 封装与 token 状态管理个人事务系统需要登录后才能操作前端通过 axios 统一处理请求头把登录后的 token 带在每次请求里。常见封装方式import axios from axios const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { if (res.code 401) { window.location.href /login } return Promise.reject(new Error(res.msg)) } return res }, error { return Promise.reject(error) } ) export default service请求拦截器统一处理 token 注入响应拦截器统一处理业务状态码。401 跳转登录页的逻辑写在这里而不是在每个页面里各自判断避免了大量重复代码。localStorage存储 token 有一个隐患XSS 攻击可以读取到但对课程设计和毕设场景来说引入 vuex-persistedstate 做会话保持已经算加分项不必强上 httpOnly Cookie。3.4 路由守卫控制页面访问权限路由配置里需要区分哪些页面需要登录。router/index.js中用全局前置守卫做拦截const router new VueRouter({ routes: [ { path: /login, component: Login }, { path: /home, component: Home, meta: { requiresAuth: true }, children: [ { path: task, component: TaskList }, { path: todo, component: TodoList }, { path: profile, component: Profile } ] } ] }) router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.matched.some(record record.meta.requiresAuth)) { if (!token) { next({ path: /login, query: { redirect: to.fullPath } }) } else { next() } } else { next() } })to.matched.some(record record.meta.requiresAuth)是判断当前路由是否包含需要鉴权的 meta 标记。这样写的好处是子路由不用每个都加判断父路由的 meta 会传导到子路由记录里。登录成功之后跳转到redirect参数指定的页面比固定跳首页体验好。4. 数据库设计与核心表结构4.1 用户表与任务表的字段设计个人事务管理系统最少需要三张表用户表、任务表、分类表。用户表存账号信息任务表存事务内容分类表用于给任务打标签。下面是最小可用版本的建表 SQLCREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(128) NOT NULL, nickname VARCHAR(50), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE t_category ( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, name VARCHAR(30) NOT NULL, sort_order INT DEFAULT 0, CONSTRAINT fk_cat_user FOREIGN KEY (user_id) REFERENCES t_user(id) ); CREATE TABLE t_task ( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, category_id INT, title VARCHAR(100) NOT NULL, content TEXT, status TINYINT DEFAULT 0, due_time DATETIME, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_task_user FOREIGN KEY (user_id) REFERENCES t_user(id), CONSTRAINT fk_task_cat FOREIGN KEY (category_id) REFERENCES t_category(id) );password字段长度设置为 128是因为业务里要考虑 MD5 加盐或 BCrypt 加密后的长度纯 MD5 是 32 位BCrypt 是 60 位。update_time使用ON UPDATE CURRENT_TIMESTAMP可以在行更新时自动刷新时间省掉 Service 层的赋值逻辑。4.2 索引设计与状态查询优化任务表最频繁的查询是按用户和时间维度某用户在某段时间范围内有哪些待办事项。这条查询在数据量上来后会很慢需要加联合索引ALTER TABLE t_task ADD INDEX idx_user_due (user_id, due_time);user_id放在联合索引最左侧因为所有任务查询都会带用户条件due_time在后面用于排序和范围过滤。还有一种场景是按status过滤未完成任务这个查询通常也会带user_id所以不单独给status建索引避免索引冗余。4.3 数据库初始化脚本的导入时机资源包里的 SQL 脚本文件通常是db_personal.sql之类的名字。导入时要注意编码问题Windows 下用命令导入mysql -u root -p --default-character-setutf8 db_personal.sql--default-character-setutf8是必须的。如果脚本里有中文注释或数据缺了这个参数导入后会出现中文乱码页面显示问号。另一个常见问题是 MySQL 版本差异5.7 的脚本导入到 8.0 可能出现utf8mb4_0900_ai_ci排序规则不兼容建议先把脚本里的ENGINEInnoDB DEFAULT CHARSETutf8mb4这部分统一再看具体报错。5. 部署验证与必踩的坑5.1 启动顺序与日志定位拿到源码后按顺序执行三个批处理最容易出现的情况是2-run.bat启动的后端端口和vue.config.js里配的 target 不一致。先确认后端启动日志里的 Tomcat 端口再确认前端代理指向同一个端口。后端启动失败时优先看两个日志Tomcat 的 localhost 日志和 MyBatis 的 SQL 日志。MyBatis 的 SQL 日志可以通过mybatis-config.xml开启settings setting namelogImpl valueSTDOUT_LOGGING/ /settings开启后控制台会打印每个 Mapper 方法执行的 SQL 和参数排查ResultMap字段映射错误非常管用。5.2 资源备份文件清理项目中残留的.bak文件在 Eclipse 或 IDEA 里不会影响编译但在打包部署时如果被一起打包Tomcat 解析 Vue 静态资源时可能遭遇文件名冲突。规范做法是删除所有.bak文件再执行3-build.bat重新打包。如果修改过前端代码但页面没变化检查浏览器缓存和dist目录是否真的更新了Vue 打包后的文件是带 hash 的文件名变了说明构建成功。5.3 接口验证的快速方法后端接口是否正常不一定要等前端页面起来。在浏览器地址栏直接访问http://localhost:8080/api/task/list?userId1如果后端没做登录拦截能看到 JSON 说明接口通如果返回 401说明拦截器生效需要先在请求头里带 token。用 Postman 或 apifox 调试接口时注意请求头的Content-Type要和服务端RequestBody的类型匹配JSON 就写application/json表单就写application/x-www-form-urlencoded写错会报HttpMessageNotReadableException。最后调试通过的标准是登录、任务新增、任务更新状态、按条件查询、删除这些主流程全部走通且刷新页面后登录状态还在。做到这一步这套 SSM Vue 的个人事务管理系统才算是真正跑明白了后续加文件上传、日历视图、数据统计功能也只是在这套分层结构上做增量开发。本文还有配套的精品资源点击获取
返回列表