ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于SpringBoot的财务管理系统:数据库设计与源码实践

基于SpringBoot的财务管理系统:数据库设计与源码实践 简介基于SpringBoot的财务管理系统毕业设计资源包面向计算机相关专业学生与需要快速搭建财务后台的开发者。系统涵盖首页、个人中心、员工、部门、工资调整、资产类别、固定资产、经营信息、序时账、年度利润及系统管理等模块功能完整。包内含450个文件约17.94MB包含123个Java源码、47个Vue页面、21个JS逻辑、16个XML配置、5个CSS样式以及SQL数据库脚本和可运行的bat批处理脚本同时附有文档和PPT演示材料前端页面、后端接口、数据库与演示文档分层清晰便于运行与二次开发。压缩包内还提供mvnw、cmd等构建支持文件方便一键启动与打包。已有56人学习适合用于毕业设计参考、课程实践以及中小型企业财务管理系统的快速起步。1. 基于SpringBoot的财务管理系统为什么先看数据库而不是源码这个标题里最有价值的不是“源码”两个字而是“设计实现数据库文档”这个组合。换句话说一个能拿去交作业、答辩、甚至二次开发的 SpringBoot 财务管理系统真正的门槛不在 Controller 里写了多少个接口而在三件事业务模块是否闭环、库表设计是否经得起查账、部署文档是否能让别人照着跑起来。我见过太多人拿到这类带源码数据库文档PPT 的压缩包第一步直接解压 IDEA 跑主类结果启动失败后连是哪张表、哪个字段对不上都说不清。正确打开方式是把整个包当成一份“可运行的需求说明书”先读 SQL 脚本理解数据结构再对照 PPT 里的模块图看 SpringBoot 代码怎么落最后才是启动调试。如果你是正在做课程设计、毕业设计或是想快速搭一个财务业务骨架的工程师这套路径对你适用如果你只想找个生成器跑个 CRUD这个标题帮不了你。2. 财务管理系统设计先于编码模块划分与业务闭环2.1 财务业务域从凭证到报表的四个层次财务系统哪怕砍到最小也必须覆盖“凭证—账簿—报表”这条主线。记账凭证记录每一笔经济业务明细账按科目归集总账汇总后生成资产负债表和利润表加上基础数据会计科目、客户/供应商与系统管理用户、角色、菜单就构成一个可以答辩的完整闭环。我在设计这类系统时一般把模块拆成 5 张表组而不是 5 个页面理由很简单页面会随着前端框架换表结构却很难推倒重来。下表是这套 SpringBoot 财务管理系统的推荐模块划分课程设计的 PPT 里通常也会按这个结构画图只是叫法略不同。业务模块核心功能关键数据表基础数据会计科目维护、客户/供应商档案account_subject、partner凭证管理记账凭证新增、审核、作废voucher、voucher_detail账簿查询明细账、总账、科目余额表ledger汇总表或视图报表统计试算平衡表、利润表、资产负债表reportSQL 聚合系统管理用户登录、角色权限、菜单sys_user、sys_role、sys_menu为什么要把“会计科目”单独放一张表因为财务系统里的科目不是普通文本它带编码规则如 1001 表示库存现金、1002 表示银行存款编码层级直接影响报表 SQL 的 like 查询和汇总。把科目表设计好后面凭证、账簿、报表都依赖它这也正是文档里“数据库设计说明”最值得写厚的部分。2.2 SpringBoot 的分层结构如何装下这些业务SpringBoot 之所以是这类系统的默认选择是因为它把配置收敛到了 application.yml把依赖收敛到了 starter让“设计实现”的重点能放在业务代码上而不是环境搭建上。这里最稳妥的组合是 SpringBoot MyBatis MySQL比 JPA 更适合财务这种需要精确控制 SQL 的场景也比纯 JDBC 少写大量样板代码。对于这个标题下的源码包拿到后先看包结构是否符合下面这种层次这直接决定后续改代码是否顺手// 包结构controller / service / mapper / entity / dto / config / common com.example.finance ├── controller // 接收 HTTP 请求做参数组装 ├── service // 业务逻辑事务边界在这里 ├── mapper // MyBatis 接口对应 XML 或注解 SQL ├── entity // 数据库实体字段与表列一一对应 ├── dto // 接口入参/出参避免实体直接暴露 ├── config // 拦截器、跨域、数据源等配置 └── common // 统一返回体、异常处理、工具类这里有个很容易被忽略的设计点Service 层是事务边界。财务系统的“新增凭证”必须同时写 voucher主表和 voucher_detail明细表两条写操作要么都成功要么都回滚所以 Transactional 要标在 Service 方法上而不是 Mapper 接口上否则一旦第二张表写失败会出现主表有记录、明细为空的对账事故。包里的文档一般是 .md 或 Word如果有“系统设计”一节通常描述的也是这个分层。3. 数据库建模财务管理系统最容易被返工的部分3.1 核心表结构与金额字段的硬性规则财务系统的表结构相比普通业务系统有几个硬性规则。金额列一律用 decimal禁止 float/double因为二进制浮点数在累计折旧、税额计算上会出现 0.10.2≠0.3 的精度问题。凭证主表和明细表必须用“主表编号行号”双重标识行号从 1 开始连续递增这是对账和凭证打印的排序依据。所有表都带 created_at、updated_at、deleted 三个字段其中 deleted 用逻辑删除而非物理删除财务数据要留痕。科目表、凭证主表和凭证明细表是三个最不能被改坏的表。以凭证明细表为例字段设计应该落在这些列上实际源码里的字段名可能略有差异但语义必须对齐字段类型说明idbigint主键自增voucher_idbigint关联凭证主表line_noint行号从 1 递增subject_idbigint会计科目 id关联 account_subjectdirectiontinyint借贷方向0 借 1 贷amountdecimal(18,2)本行金额禁止 floatsummaryvarchar(255)摘要biz_datedate业务日期区别于系统时间财务系统里“记账日期”和“系统日期”是两个概念月末关账时要按 biz_date 查询而不是 created_at。3.2 用初始化 SQL 把库和基础数据一次建好标题里“数据库”指的就是这个 SQL 脚本目录通常叫 init.sql 或 finance.sql。拿到后不要双击盲跑先在命令行里用 source 执行执行成功再打开 Navicat 看表数量是否符合预期。下面这段是精简的建表与初始化示例可以对照验证你自己的脚本结构CREATE DATABASE IF NOT EXISTS finance_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE finance_db; DROP TABLE IF EXISTS account_subject; CREATE TABLE account_subject ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, subject_code VARCHAR(20) NOT NULL COMMENT 科目编码如 1001, subject_name VARCHAR(100) NOT NULL COMMENT 科目名称, subject_type TINYINT NOT NULL COMMENT 1资产 2负债 3权益 4成本 5损益, parent_id BIGINT DEFAULT NULL COMMENT 上级科目 id, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted TINYINT DEFAULT 0 COMMENT 逻辑删除0正常 1删除 ) ENGINEInnoDB COMMENT会计科目表; INSERT INTO account_subject (subject_code, subject_name, subject_type) VALUES (1001, 库存现金, 1), (1002, 银行存款, 1), (1122, 应收账款, 1), (2202, 应付账款, 2), (6001, 主营业务收入, 5);这段 SQL 里有几个点要说明库名用IF NOT EXISTS避免重复执行时直接报错utf8mb4 不是可有可无因为凭证摘要里可能存人名和单位名utf8 存不了生僻字科目类型用数字而不是字符串是为了报表 SQL 里能按 subject_type 分组聚合逻辑删除默认 0后续代码里所有查询都要带deleted 0。执行方式最常见的是 Navicat 里选中连接后“运行 SQL 文件”或者命令行执行mysql -uroot -p finance_db init.sql。执行完确认三件事表数量与文档的“数据字典”一致、account_subject 有 5 条以上基础科目、voucher 和 voucher_detail 存在对应索引。如果脚本里没有外键不要强行加MyBatis 体系里外键更多是写文档用的代码里靠事务保证一致性。3.3 当表不存在自动建表脚本建表与自动建表的取舍SpringBoot 项目里经常出现“当表不存在自动建表”的诉求比如 mybatis-plus 的 ddl-auto 或spring.sql.init.modealways。财务管理系统不推荐依赖自动建表原因很现实自动建表只能生成结构生成不了科目、角色、菜单这批基础数据而这些数据恰恰是财务系统能跑起来的前提。我的建议是结构用 SQL 脚本托管版本化入库SpringBoot 侧设置spring.sql.init.modenever或按环境打开避免每次启动都重新执行一遍导致数据幂等出问题。真要自动化至少用 Flyway 管理版本而不是靠启动时无条件执行。4. SpringBoot 源码落地从实体到接口的最小路径4.1 项目骨架与 SpringBoot 配置starter 依赖和 application.yml源码包里的核心是 SpringBoot 工程第一步看 pom.xml 的 parent 版本。常见做法是用 SpringBoot 2.7.x 搭配 JDK 8因为很多课程设计是在机房或旧笔记本上跑的JDK 环境普遍是 8如果 pom 里写的是 SpringBoot 3.x那本地 JDK 必须是 17 以上这往往是启动失败的第一个隐藏原因。mapper 层用 mybatis-spring-boot-starter 而不是 mybatis-plus除非源码里明确引了 plus这类系统的 SQL 手写更直观。application.yml 是全文最值得逐行看一遍的 SpringBoot 配置它通常长这样server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/finance_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 sql: init: mode: never mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.finance.entityurl 里为什么要带serverTimezoneAsia/Shanghai因为 MySQL 8.x 驱动对时区敏感不指定时区会报 “Server returns invalid timezone” 的错误这也是“数据库连不上”类问题里最高频的一个。password 用明文是课程设计常态但真实项目要用 Jasypt 做 yml 密文把明文密文放到环境变量里。如果后续想把基础数据一起初始化把 mode 改成 always但要确保 SQL 里全是create table if not exists和insert ignore否则每次启动都会重复插入。4.2 凭证业务的实现实体、Mapper 与事务实体类一般用 Lombok 简化 getter/setter字段与表列一一对应。Mapper 接口里只写 SQL 相关方法业务规则放 Service。以“新增凭证”为例Service 里的实现决定了这套系统能不能过答辩我把最小实现写出来Service RequiredArgsConstructor public class VoucherServiceImpl implements VoucherService { private final VoucherMapper voucherMapper; private final VoucherDetailMapper detailMapper; Override Transactional(rollbackFor Exception.class) public Long addVoucher(VoucherDTO dto) { Voucher voucher new Voucher(); voucher.setBizDate(dto.getBizDate()); voucher.setStatus(0); // 0 草稿 1 已审核 voucherMapper.insert(voucher); int lineNo 1; for (VoucherDetailDTO item : dto.getItems()) { VoucherDetail detail new VoucherDetail(); detail.setVoucherId(voucher.getId()); detail.setLineNo(lineNo); detail.setSubjectId(item.getSubjectId()); detail.setDirection(item.getDirection()); detail.setAmount(item.getAmount()); detailMapper.insert(detail); } return voucher.getId(); } }这段代码的关键点有三个。第一Transactional 在 Service 层保证凭证主表和明细表要么一起插入成功要么一起回滚这是财务系统的基本底线。第二凭证状态用 int 而不是 String草稿/审核/作废的可读性由代码常量维护避免一不留神把状态值写错。第三行号 lineNo 在内存里自增而不是靠数据库生成这样凭证打印和明细排序就稳定可控。金额在 Service 层用 BigDecimal 接收前端传来字符串也不要急着转 double。Controller 层要守住一个原则只做参数接收、session 鉴权和结果包装不写业务。参考下面的写法RestController RequestMapping(/api/voucher) public class VoucherController { private final VoucherService voucherService; PostMapping public ResultLong create(RequestBody Valid VoucherDTO dto, HttpSession session) { Long id voucherService.addVoucher(dto); return Result.success(id); } }统一返回体 Result 里至少要有 code、message、data 三个字段code200 表示成功。答辩时老师常问“异常怎么办”所以全局异常处理类要捕获业务异常并转成 Result 返回不让堆栈直接暴露给前端。4.3 报表查询用 SQL 聚合而不是 Java 内存计算财务报表的常见错误是循环查库算总额性能差且代码难读。试算平衡表最好在 Mapper XML 里用一条分组查询实现select idselectTrialBalance resultTypemap SELECT s.subject_code, s.subject_name, SUM(CASE WHEN vd.direction 0 THEN vd.amount ELSE 0 END) AS debit_total, SUM(CASE WHEN vd.direction 1 THEN vd.amount ELSE 0 END) AS credit_total FROM voucher_detail vd JOIN account_subject s ON vd.subject_id s.id JOIN voucher v ON vd.voucher_id v.id WHERE v.status 1 AND v.deleted 0 AND vd.deleted 0 AND v.biz_date BETWEEN #{startDate} AND #{endDate} GROUP BY s.subject_code, s.subject_name ORDER BY s.subject_code /select这里的SUM(CASE WHEN …)是经典的借贷方行列转换写法direction0 进借方列direction1 进贷方列一条 SQL 同时出两列。注意v.status 1这个过滤条件未审核凭证不能进报表这也是财务系统“审核不过不进账”的规则在 SQL 层面的体现。5. 把源码数据库跑起来导入、配置与常见启动失败5.1 从 ZIP 到可运行导入 IDE 的四个关键点拿到压缩包后先解压不要直接双击 zip 里的文件。导入步骤按顺序做IDEA 里 File → New → Project from Existing Sources 选择解压目录选 Maven等依赖下载检查 lombok 插件然后配置 JDK。这四个步骤里最容易翻车的是 lombok如果不装插件实体类会报“找不到 getter/setter”但源码本身没有错误答辩现场容易被误判为代码 bug。Eclipse 用户则要注意导入的是 Maven 项目而不是普通 Java 项目。SpringBoot 版本太高的坑在这个阶段就会出现pom 里写 3.x本地是 JDK 8项目直接跑不起来报错内容是 UnsupportedClassVersionError。应对方式是查清楚本地 JDK 版本再决定是否把 parent 版本降级到 2.7.x、同时把 pom 里的 javax 换成 jakarta 下的包。不要一上来就升级本地 JDK机房电脑未必允许重装。依赖下载完成后看 Maven 面板里有没有红色报错。如果 mybatis-spring-boot-starter 和 mysql-connector-j 一直无法解析大概率是 settings.xml 里的镜像源问题换阿里云镜像源是常见解法改完记得重新导入一次让 IDEA 重新拉取依赖。5.2 数据库初始化和连接配置执行 SQL 脚本的方式前面已经说过这里强调顺序问题先建库建表再启动 SpringBoot。不要指望项目一启动自动把表建好这个标题下的源码包通常不配置自动建表数据库脚本才是权威。执行成功后在 Navicat 里确认 finance_db 存在并把 application.yml 里的用户名密码改成你能连上的值。命令行执行时可以加个显式密码提示避免把密码留在历史记录里mysql -uroot -p finance_db /path/to/init.sql回车后输入密码即可。如果脚本里没有 CREATE DATABASE 语句需要先手动建库再把文件导进去否则会报 No database selected。另外注意脚本文件的编码Windows 上记事本另存的 SQL 是 GBK导入后中文注释会变乱码用 Navicat 导入时选 utf8 可以规避。5.3 高频启动失败与排查顺序启动失败时先看控制台第一行异常栈而不是翻完整页日志。以下是三类高频问题现象原因排查/解决Could not create connection to database server驱动类写错或 MySQL 版本不匹配确认 driver-class-name 是 com.mysql.cj.jdbc.DriverMySQL 8还是 com.mysql.jdbc.DriverMySQL 5Server returns invalid timezoneURL 没带 serverTimezoneURL 加 serverTimezoneAsia/ShanghaiPort 8080 was already in use端口被占用改 server.port或 netstat -ano 找到 PID 结束进程启动成功后用浏览器访问/login或/index.html如果看到登录页说明静态资源没有配错。此时再用 Postman 调一个需要权限的接口返回 401 说明拦截器生效。这套验证顺序跑完源码数据库文档对应关系就基本清晰了。6. 财务骨架上的进阶技巧金额精度、登录拦截与答辩演示财务管理系统做到能跑只是第一步答辩和后续改进都藏在三个细节里金额精度、登录会话、演示顺序。金额精度上所有涉及金额的实体字段都用 BigDecimal且配置序列化方式避免前端收到科学计数法数字。字段上加JsonFormat(pattern 0.00)数据库端保持 decimal(18,2)。试算平衡的判断不能用 equalsBigDecimal 的 scale 不同会导致 equals 返回 false必须用 compareTo。这个点答辩时提出来比背概念得分高。登录拦截器是课程设计里“系统管理”模块的得分点。不引 Spring Security 的话用一个 HandlerInterceptor 就能实现最小可用版本public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user request.getSession().getAttribute(loginUser); if (user null) { response.sendRedirect(/login); return false; } return true; } }关键在注册配置里排除登录接口和静态资源否则登录页样式全失效。拦截器只做会话校验角色判断放到 Service 层避免拦截器越做越重。PPT 和文档的用法要分清场合。如果是拿这套资料答辩演示顺序建议按下面的节奏走阶段演示内容对应源码位置业务闭环新增一张凭证查询明细账和试算平衡表VoucherController、VoucherServiceImpl数据设计打开科目表和凭证明细表讲为什么用 decimal 和 biz_dateinit.sql、account_subject实现亮点演示新增凭证时写坏一张表后事务回滚VoucherServiceImpl.addVoucher这三个阶段正好覆盖“懂业务、懂设计、懂实现”三层考察点。如果你在写自己的文档把 PPT 的每一章对应到源码里实际存在的类不要让 PPT 出现源码里不存在的模块。演示前固定端口、统一字符集为 utf8mb4、把浏览器缩放调成 100%这些细节比堆动画更能稳住现场。最后试着从凭证入口新增一笔业务并导出一张报表如果台账对得上这骨架就真正立住了。本文还有配套的精品资源点击获取
返回列表