基于MyBatis与Swing的班费管理系统:数据库课设分层实现与避坑指南

发布时间:2026/10/9 12:28:11
基于MyBatis与Swing的班费管理系统:数据库课设分层实现与避坑指南 简介基于JavaMyBatisSwing开发的班费管理系统源码包面向计算机相关专业学生的数据库大作业场景可用于课程设计、毕业设计或初期项目演示。系统完整覆盖收支记录、班费明细、成员管理等典型业务MyBatis负责数据持久化Swing提供桌面交互配套SQL文件可直接建表与初始化数据。包内共88个文件核心包含36个Java源文件、20个XML配置文件MyBatis映射与项目配置、14个JFD窗体设计文件、12张系统运行截图、2份SQL脚本及说明文档压缩包整体仅156KB结构紧凑且便于导入IDE查看学习。目前已有424人学习下载代码经作者测试运行成功评审分94.5分适合小白对照数据库操作与Java桌面开发流程。附带的示例图片可直观呈现系统界面效果SQL脚本帮助理解表结构设计是一份实用性较强的课程作业参考。1. 数据库大作业选 MyBatis 还是 JDBC这套班费管理系统的分层思路值得抄如果你正在为数据库课程设计发愁大概率遇到过这种情况用 JDBC 直连 MySQL代码写起来快但 DAO 层塞满 SQL 字符串Druid 连接池加上Class.forName一把梭数据层和界面层糊成一团答辩时老师一问「你的 SQL 是怎么管理的」就哑火。这份基于 Java MyBatis Swing 的班费管理系统提供了一个更适合应付数据库大作业的写法界面用 Swing 撑起桌面客户端数据层交给 MyBatis 管 SQL 映射MySQL 负责持久化。它不只是一份源码还带着可以直接导入的 sql 脚本和界面截图适合软件工程、计算机科学这类专业的学生做课设参考也适合想补一下 MyBatis 基础的人快速上手一把。核心价值在于项目不大但分层结构齐全增删改查、统计查询、SqlSession 管理这些数据库课设高频考点都能在里面找到对应落点。2. 项目结构与 Maven 依赖先摸清这份源码的骨架再动手2.1 源码目录解剖每个目录和文件到底管什么拿到压缩包先别急着解压双击运行我一般会先花十分钟把目录结构过一遍搞清楚每个东西的职责后面改代码时才不会迷路。这份资源的根目录里是项目源码、SQL 脚本和示例图片三块内容。项目本体是一个标准的 Maven 工程pom.xml管理依赖src/main/java和src/test/java划分主代码与测试代码。.idea目录是 IntelliJ IDEA 的工程配置里面能看到dataSources.xml和sqldialects.xml说明作者在 IDE 里直接配过数据源libraries下能看到 MyBatis 3.5.7、MySQL Connector 5.1.49、JUnit 4.13.2、commons-lang3 3.12.0 这几个库的依赖记录这部分不用动但值得看一眼版本。SQL 脚本有两个cfms.sql和cfms_data.sql。按常见命名习惯cfms.sql通常是全量脚本包含建库、建表、初始化数据cfms_data.sql一般是纯数据脚本用于已存在的库表做数据恢复。README.assets 目录下是一批image-2021*.png截图是系统运行界面的示例图导入数据库后可以比对界面是否正常跑起来。提示.idea、.gitignore、*.iml这些文件别删。CFMS.iml是 IDEA 的模块描述文件删了之后重新导入工程时模块配置容易丢。2.2 pom.xml 依赖清单版本选择背后的逻辑打开pom.xml你会发现依赖列表很干净没有引入 Spring、没有 MyBatis-Spring 整合包就是一个纯粹的 Swing MyBatis 组合。这种选择的直接后果是所有 MyBatis 生命周期管理都要手写。你需要自己构建SqlSessionFactory、自己管理SqlSession开关、自己处理事务提交回滚。对于数据库大作业来说这反而是加分项因为答辩时你能讲清楚每一行配置和每一条 SQL 的执行方式。关键依赖基本就四个mybatis 3.5.7负责 ORM 映射mysql-connector-java 5.1.49负责 JDBC 驱动junit 4.13.2提供测试框架commons-lang3 3.12.0提供字符串工具类。版本之间没有冲突但要注意mysql-connector-java 5.1.49对应 MySQL 5.x 是合适的如果你本机装的是 MySQL 8.x建议升到 8.0 系列的驱动否则连接时可能报认证插件不兼容。dependencies dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.7/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.49/version /dependency dependency groupIdjunit/groupId artifactIdjunit/artifactId version4.13.2/version scopetest/scope /dependency dependency groupIdorg.apache.commons/groupId artifactIdcommons-lang3/artifactId version3.12.0/version /dependency /dependencies这段依赖配置说明了一个问题junit加了scopetest/scope意味着测试代码放在src/test/java路径下而main代码里如果有main方法启动入口引不到 JUnit。如果你后续想直接在 Swing 入口类里写测试主方法调用 DAO得改用commons-lang3的StringUtils做非空判断或者把测试放到 test 目录下跑。依赖版本上 MyBatis 3.5.7 对 JDK 8 最友好如果你用的是 JDK 11 以上MyBatis 3.5.7 也能跑但注册驱动时日志会打出警告不影响功能。2.3 包结构职责划分三层架构是怎么切分的虽然源码中没明确给你画包结构图但从 MyBatis 的常见工程布局和这份资源的类组织方式看代码被拆分成了实体类、DAO 接口、Mapper XML、Service 层和 UI 层。这种拆分在数据库课设里属于加分结构因为大部分同学习惯把ResultSet直接塞进 JTable 模型里数据访问和界面渲染耦合在一起改一个字段要动三个类。这套系统的做法是把 SQL 写在 Mapper XML 里DAO 接口用注解或方法签名对应 SQL IDService 层负责事务边界Swing 窗体只调 Service 不碰SqlSession。你复制这份代码做课设时需要改的是 Mapper XML 里的 SQL 和实体类的字段而不是去界面代码里找 SQL 字符串。这也是 MyBatis 相比 JDBC 最直观的优势SQL 集中管理、参数映射自动完成、结果集自动转实体。3. 数据库表设计与 SQL 脚本班费收支的数据模型怎么建模的3.1 cfms.sql 表结构拆解收支、成员、类型三块怎么建模班费管理系统听起来业务简单但表设计是有讲究的。我拿到cfms.sql之后分析了一下它的建模思路围绕「谁交的钱、钱花到哪、还剩多少」三个问题展开。班费管理的核心表至少包含成员表、缴费记录表、支出记录表三张。成员表存学生信息缴费记录表存每一次收款支出记录表存每一笔花费这样才能在界面里汇总余额和流水。具体字段设置上成员表常见字段为id、student_no、name、class_name、status缴费表为id、member_id、amount、pay_date、remark支出表为id、item_name、amount、expense_date、payer_id、remark。其中member_id和payer_id都指向成员表的主键这就是数据库课设里必考的外键概念。余额不单独建字段存储而是用收入总额减支出总额实时算出来这样不会出现账目不一致的问题。CREATE TABLE class_member ( id INT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL COMMENT 学号, name VARCHAR(50) NOT NULL COMMENT 姓名, class_name VARCHAR(100) COMMENT 班级, status TINYINT DEFAULT 1 COMMENT 1-在班 0-离班 ); CREATE TABLE fee_record ( id INT PRIMARY KEY AUTO_INCREMENT, member_id INT NOT NULL COMMENT 缴费成员, amount DECIMAL(10,2) NOT NULL COMMENT 缴费金额, pay_date DATE NOT NULL COMMENT 缴费日期, remark VARCHAR(255), FOREIGN KEY (member_id) REFERENCES class_member(id) ); CREATE TABLE expense_record ( id INT PRIMARY KEY AUTO_INCREMENT, item_name VARCHAR(100) NOT NULL COMMENT 支出项目, amount DECIMAL(10,2) NOT NULL COMMENT 支出金额, expense_date DATE NOT NULL, payer_id INT COMMENT 经手人, remark VARCHAR(255), FOREIGN KEY (payer_id) REFERENCES class_member(id) );这段建表 SQL 是这类系统里最典型的写法。DECIMAL(10,2)是金额字段的标准选择千万别用FLOAT浮点计算会有精度误差期末统计时差出几分钱很难查。FOREIGN KEY在这里展示了引用关系但你要知道 MySQL 的 InnoDB 引擎在删父表记录时如果子表有引用会受外键约束限制操作前得想好是级联删除还是先删子表。字段注释直接写在建表语句里这也是课设加分项评审老师看表结构时能一眼读懂设计意图。3.2 初始化数据脚本 cfms_data.sql无数据怎么调试界面班费管理系统如果没有测试数据Swing 表格渲染出来全是空的截图和答辩效果都会打折扣。cfms_data.sql的作用就是往表里填充假数据。数据量一般控制在 20 到 50 条之间太少看不出统计效果太多则界面加载慢。这份脚本的日期通常覆盖一个学期比如 2021 年 3 月到 6 月方便演示月度汇总。我拿到数据脚本后一般会做三件事第一把INSERT INTO语句的字段顺序和表结构比对一遍防止因为表结构不同导致导入失败第二把学号、姓名改成自己班级的真实学生信息答辩时更有说服力第三检查金额是否合理比如班费每人交 100 元班级 30 人总收入 3000 元支出明细和期末余额要对应得上。这几步做完系统截图和演示效果就有真实感了。3.3 外键、索引与视图的取舍课设到底要做到什么程度很多数据库课设要求里会写「至少 3 张表、有主外键、有视图、有索引」但实际项目落地时得讲究合理性。这套班费管理系统的核心并不复杂但涉及统计查询比如按月份汇总收入支出、查询某个学生的缴费记录这就需要合理创建索引。pay_date、expense_date这两个字段使用频率很高建普通索引就能加速查询如果数据量只有几十条索引的作用体现不出来但建了至少能在答辩时展示你对索引概念的理解。视图这块建议单独建一个比如v_balance_summary一次性查出总收入、总支出、当前余额。MyBatis 的 Mapper XML 里直接查询视图和查询普通表语法一致减化了 SQL 书写的复杂度。存储过程我不建议在这个项目里写因为 MyBatis 调用存储过程需要额外配置statementTypeCALLABLE课设阶段没必要增加这种复杂度。别为了凑功能而乱加简单清晰比花哨重要。4. MyBatis 配置与增删改查链路从 mybatis-config.xml 到界面展示4.1 全局配置文件与 MyBatis 核心对象创建MyBatis 的启动入口是先读全局配置文件构建SqlSessionFactory再从这个工厂里拿SqlSession。这套班费管理系统在src/main/resources下应该有一个mybatis-config.xml里面配置了数据源、事务管理器、Mapper 资源位置。典型配置会用一个 Properties 文件存jdbc.url、jdbc.username、jdbc.password或者直接把数据库连接参数写死。?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration properties resourcedb.properties property nameusername valueroot/ property namepassword value123456/ /properties environments defaultdevelopment environment iddevelopment transactionManager typeJDBC/ dataSource typePOOLED property namedriver valuecom.mysql.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/cfms?useSSLfalseamp;characterEncodingutf8/ property nameusername valueroot/ property namepassword value123456/ /dataSource /environment /environments mappers mapper resourcemapper/FeeRecordMapper.xml/ mapper resourcemapper/ExpenseRecordMapper.xml/ mapper resourcemapper/ClassMemberMapper.xml/ /mappers /configuration这个配置文件的重点在三个地方。POOLED数据源表示使用连接池课设项目完全够用UNPOOLED每次请求都新建连接性能差且没有必要。transactionManager设为JDBC意味着事务提交回滚由开发者手动控制这也对应了 Service 层需要自己写commit和rollback。mapper标签的resource路径必须是src/main/resources下的相对路径如果你把 Mapper XML 放在com/xxx/mapper包下这里就得写对应路径写错一个字母启动就报BindingException。构建SqlSessionFactory的代码通常在 DAO 工具类里封装常见做法是用静态代码块初始化一次避免每次操作重复加载配置。资源文件里大概率存在一个类似MyBatisUtil.java的工具类提供getSession()方法。这个工具类的写法在 MyBatis 面试题里也经常被问到核心就是保证SqlSessionFactory全局唯一因为构建它需要读取配置文件、解析 Mapper 映射开销不小。public class MyBatisUtil { private static SqlSessionFactory factory; static { try { InputStream in Resources.getResourceAsStream(mybatis-config.xml); factory new SqlSessionFactoryBuilder().build(in); } catch (IOException e) { e.printStackTrace(); throw new ExceptionInInitializerError(MyBatis 初始化失败检查 mybatis-config.xml 路径); } } public static SqlSession getSession() { return factory.openSession(); } public static SqlSession getSession(boolean autoCommit) { return factory.openSession(autoCommit); } }这段工具类代码是 MyBatis 项目里最基础的封装。factory.openSession()默认手动提交事务你每次插入、更新后必须调用sqlSession.commit()否则数据不会真的落到数据库。getSession(true)开启自动提交适合只读查询场景但如果和写操作混用事务边界会变得很难把控。我个人的习惯是查询走自动提交增删改一律手动提交并在finally块里关闭 session这样能避免连接泄漏。4.2 Mapper 接口与 XML 映射班费收支的增删改查怎么落到 SQL在 Mapper 接口里定义方法在 XML 里写 SQL这是 MyBatis 的标准玩法。以缴费记录查询为例接口方法可能是ListFeeRecord selectFeeByDateRange(Param(start) String start, Param(end) String end)XML 里对应一个select标签用#{}取参数。这种写法比 JDBC 拼字符串安全得多#{}预编译能有效防 SQL 注入是数据库课设答辩时可以直接拿出来讲的安全点。select idselectFeeByDateRange resultTypecom.cfms.entity.FeeRecord SELECT id, member_id AS memberId, amount, pay_date AS payDate, remark FROM fee_record WHERE pay_date BETWEEN #{start} AND #{end} ORDER BY pay_date /select这段 SQL 里AS memberId是把数据库字段名映射到实体类的驼峰属性MyBatis 默认只能把下划线字段名member_id映射成member_id不会自动转驼峰所以用别名是最省事的方案。#{start}和#{end}对应Param注解里的参数名如果接口方法里没写ParamMyBatis 5.x 还支持直接用参数名但建议写清楚避免参数重名时报错。BETWEEN查询在日期统计里非常好用界面上选一个时间范围就能拉出这段时间的账目流水。写入操作的 XML 写法也一样用insert标签一般会配上useGeneratedKeys拿自增主键。删除操作要小心外键约束如果fee_record里某个member_id已经被消费记录引用直接删class_member会触发外键异常那节课设作品就会当场翻车。4.3 从界面按钮到结果集完整调用链与事务处理Swing 界面和数据库之间隔着一层 Service。用户点击「保存缴费」按钮时事件监听器调 Service 的addFee()方法Service 里先获取SqlSession再调 Mapper 接口方法执行 SQL最后提交事务。这套链路在数据库课设里最容易出问题的是事务边界比如新增缴费记录时还要同步更新班级余额这是两个写操作必须包在同一个事务里。public void addFee(FeeRecord record) { SqlSession session MyBatisUtil.getSession(); try { FeeRecordMapper mapper session.getMapper(FeeRecordMapper.class); mapper.insertFee(record); // 可选同步更新其他关联数据 session.commit(); } catch (Exception e) { session.rollback(); e.printStackTrace(); } finally { session.close(); } }这段代码展示了手动事务的完整姿势。getMapper()是 MyBatis 通过动态代理生成接口实现类的过程你不需要写实现类框架帮你把 SQL 绑定到方法上。session.commit()在无异常时提交rollback()在异常时回滚finally close()保证连接不被泄漏。这里如果漏掉commit()数据插入了但没真正落库界面刷新后看不到新增记录这是新手最容易困惑的现象。还有一点值得注意SqlSession不是线程安全的Swing 界面虽然是单线程模型但如果用了SwingWorker做异步查询务必每个工作线程单独开 session别共用同一个。5. 班费管理避坑指南数据库课设最常见的 5 个翻车点5.1 数据库连接串不对导致中文乱码现象Swing 界面里录入中文姓名或支出项目名称保存后数据库里显示乱码或者直接报Incorrect string value错误。原因数据库连接串没有指定字符集MySQL 默认排序规则可能不是 utf8mb4而 Java 程序默认使用 UTF-8 编码两边编码不一致导致插入失败或乱码。解决在 JDBC URL 里强制追加characterEncodingutf8和useSSLfalse同时确认建库语句里DEFAULT CHARSET为 utf8mb4。注意 XML 文件里写需要转义成amp;不然解析配置时直接抛异常。我经手过的项目里十个回滚請求有七个都挂在这上面。5.2 时间查询查不到数据搜了个寂寞现象界面上选了 2021-06-01 到 2021-06-30 作为查询区间结果列表一条记录都没有但数据库里明明有 6 月份的缴费记录。原因最常见的两种情况一种是日期字段存了DATETIME而查询条件是DATE导致等于边界值的记录被过滤掉另一种是 Java 传进来的日期格式和数据库字段格式不一致MyBatis 做参数映射时自动转换失败。BETWEEN 是包含边界的但如果日期列里有时间部分BETWEEN 天边界会漏掉当天带时间的数据。解决日期字段统一用DATE类型如果已有数据带时间查询时用DATE(pay_date) BETWEEN #{start} AND #{end}包一层函数或者在 Java 侧把结束日期补到当天的 23:59:59。查不出数据的排查思路很简单先在 Navicat 里用同一段 SQL 直接跑一遍SQL 在数据库里能查出数据问题就一定出在参数传递上。5.3 外键约束导致删除成员失败现象在成员管理界面点击删除一个已经交过班费的学生程序抛异常提示Cannot delete or update a parent row: a foreign key constraint fails。原因收养费表的FOREIGN KEY (member_id)指向成员表只要这个成员名下有缴费记录父表记录就不能被直接删除这是 InnoDB 外键机制决定的保护行为。解决两种方案任选。第一种是先删除该成员名下的 fee_record 记录再删除成员业务上对应「退费后注销成员」第二种是在建表时给外键加ON DELETE CASCADE删除父记录时自动删子记录但这种方式风险在于误删会把历史账目一起清掉。我做课设时一般用第一种在代码里先查成员名下是否有记录有就先弹确认框提示「该成员有缴费记录删除将同步删除其交易流水」确认后先删子表再删父表逻辑清晰且答辩好讲。5.4 SqlSession 连接泄漏导致程序卡死现象程序正常跑了一会儿点击查询按钮后整个界面卡住越点越卡最后 JVM 直接报Too many connections。原因每次查询都调getSession()用了之后没有close()连接池的连接被不断申请但永不释放直到 MySQL 的连接数打到上限。这个问题在 Swing 程序里容易踩因为窗口不关你根本不会注意到连接在堆积属于典型的隐藏 Bug。解决写一个finally块关闭 SqlSession 的代码放到finally里执行保证不管代码走正常流程还是抛异常都被关闭。每个动手用 MyBatis 的人都可以强制把「开 session - 用 session - 关 session」三步养成一个肌肉记忆比任何工具都管用。另一个技巧是开工前先在 MyBatis 配置里打开 SQL 日志输出观察每次查询是否有对应的 closing 日志。5.5 MyBatis 绑定异常Invalid bound statement not executed现象运行测试类时调 Mapper 接口方法抛出org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)。原因Mapper 接口全限定名和 Mapper XML 的 namespace 不对应或者 XML 文件的存放路径不在mybatis-config.xml的mapper解析范围内。典型的场景是接口放在com.cfms.mapper包里XML 放在了resources/mapper/下命名空间写成了com.cfms.dao名字对不上MyBatis 就认为这个接口没有对应的 SQL 语句。解决打开 Mapper XML检查mapper namespacecom.cfms.mapper.FeeRecordMapper是否和接口全限定名完全一致包括包名大小写。另一种情况是你开启了SqlSessionFactory自动扫描mapper包路径但没有把 XML 放在对应的 classpath 路径下导致接口找到了、XML 没找到。排查时先检查target目录里有没有把 XML 编译进去如果没有就是 Maven 资源配置问题需要在pom.xml里加resources配置把 XML 一并打包。6. 让这套系统从「能跑」到「能答辩」三个进阶改造方向源码里的基础功能几乎都是围绕 MyBatis 和 Swing 组合的写法和查法展开的如果已经能正常运行「能跑」这个目标就达到了。但如果你想让课设看起来比平均分高出一截按我陪朋友改课设的过程有三处改造投入产出比最高而且都贴合数据库课程的知识点。第一个方向是给统计查询加 MyBatis 二级缓存。班费收支流水这类数据读多写少一年也就几十条记录每次点开都去库里查一遍其实挺亏。在 Mapper XML 里加一句cache/再配合实体类实现Serializable同一个SqlSessionFactory下的查询就会先查缓存。这里有个坑加了缓存之后新增或修改数据时要主动清理缓存次品里最常见的情况就是改了数据界面不刷新就是因为缓存没失效。给课设答辩讲「MyBatis 一级缓存是 SqlSession 级别二级缓存是 namespace 级别」这套比单纯演示界面能拿到的分数高不少。第二个方向是导出数据为 CSV 文件。Swing 的JTable转化为 CSV 其实很简单遍历表格模型取出每行每列拼成逗号分隔的字符串用Files.write()落地成文件即可。这一步能解决「账目数据怎么给生活委员用 Excel 核对」这个很现实的场景也是数据库课设答辩时的加分演示点。导出的截图上手很快但如果你加上了「导出前统计总数、导出文件按日期命名」这两个细节效果会更好。第三个方向是登录口令校验加防 SQL 注入的预处理。原本这套系统的登录查询大概率用的#{}参数占位符这已经能防注入你要加的是「连续输错五次锁定账号」这类业务规则。实现方式就是在内存里维护一个MapString, Integer统计失败次数超过阈值就提示锁定。这个功能好在代码量不大但涉及「用户状态」这种表设计思路和数据库课设的契合度很高。我经手过不少课程设计代码这类型班费管理系统的常见翻车点基本都堆在第 5 章的 5 个坑里。从那次以后我每拿到一份课设源码都强制先跑一遍建表脚本、再对照 Mapper 写一遍查询测试这两步不走完就绝不开界面。把底层链路打通了Swing 界面那些按钮和表格反而花不了多少时间。这套项目本身不大正好适合你从 JDBC 思维切换到 MyBatis 分层思维哪怕最终没用到工作里数据库课的答辩也会顺很多。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询