news 2026/10/22 12:16:59

Java银行管理系统实战:IDEA+Swing+MySQL从零搭建课程设计项目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java银行管理系统实战:IDEA+Swing+MySQL从零搭建课程设计项目

简介:这是一套面向Java初学者与课程设计学习者的银行管理系统项目源码,基于IntelliJ IDEA开发,采用Java Swing构建图形界面,以MySQL作为后台数据存储,实现管理员与顾客两类角色的完整业务闭环。管理员端支持登录验证、添加与删除顾客、统计存储金额;顾客端涵盖登录、存款、取款、转账、修改密码、查看交易记录及安全退出等功能,适合作为Java面向对象编程、数据库应用与Swing界面开发的综合练习素材。资源包为rar压缩格式,共28个文件,约40KB,其中包含14个class编译文件、6个xml与2个yml配置、2个html页面、1个java源码及说明文档,覆盖项目结构、依赖配置与构建产物,便于直接导入IDEA运行调试。目前已有424人学习浏览,可帮助读者快速理解银行系统的模块划分、数据表设计与前后端交互逻辑,积累金融类软件开发的实战经验。

1. 从一张课程设计截图说起:Java 银行管理系统到底在练什么

很多人第一次见到「Java 银行管理系统(IDEA项目/JavaSwing界面/MySQL数据库)」这个标题,是在课程设计选题表或者简历项目栏里。它看起来像个玩具,但真正动手做过的人知道,这套东西把 Java 桌面开发最核心的三条链路一次性串了起来:Swing 负责把界面画出来,JDBC 负责把数据写进 MySQL,IDEA 负责把这两者组织成一个能跑、能调试、能打包的工程。它解决的不是「银行怎么运转」,而是「一个带登录、开户、存取款、转账、流水查询的桌面程序,怎么从零搭到能演示」。

适合谁?一是刚学完 Java 基础、面向对象编程,想找一个能写进简历的完整案例的在校生;二是想从控制台程序过渡到带界面、带数据库的 JavaWeb 项目完整案例的初学者;三是需要快速交付一个课程设计或实训作业的开发者。它不涉及高并发、分布式,但把「界面事件 → 业务逻辑 → 数据库持久化」这条主线走通了,后面换 Spring Boot + MyBatis 只是换框架,思路是一样的。

2. 环境与工程骨架:IDEA、MySQL、Swing 三件套怎么配才不翻车

2.1 为什么选 Swing 而不是 JavaFX,选 MySQL 而不是 SQLite

先说选型。Swing 是 JDK 自带的,不需要额外引入依赖,IDEA 社区版新建项目就能直接写,这对课程设计场景是决定性的优势——你不需要折腾模块化配置,也不需要处理 JavaFX 在 JDK 11 之后被剥离的问题。JavaFX 界面确实更现代,但一旦遇到「IDEA 运行 JavaWeb 项目配置」这类环境问题,排查成本会成倍上升。Swing 的组件模型虽然老,但JFrame、JPanel、JTable、JButton这套东西足够撑起银行管理系统的所有界面。

数据库选 MySQL 而不是 SQLite,理由更实际:MySQL 安装配置教程满地都是,mysql installer for windows一路下一步就能装好,而且银行管理系统天然需要多表关联——用户表、账户表、交易流水表,MySQL 的外键、事务、存储过程都能用上。SQLite 虽然零配置,但面试官看到你项目里写的是 MySQL,默认你对 JDBC、连接池、SQL 语句是有概念的。

提示:MySQL 5.7 和 8.0 在 JDBC 驱动类名和连接 URL 上有差异,5.7 用com.mysql.jdbc.Driver,8.0 用com.mysql.cj.jdbc.Driver,URL 还要加时区参数。选一个版本从头到尾用,别中途换。

2.2 用 IDEA 建工程:目录结构与依赖引入

打开 IDEA,新建一个 Java 项目,不要选 Maven 或 Gradle,课程设计阶段用普通 Java 项目最省事。建好之后,在项目根目录下新建lib文件夹,把 MySQL 的 JDBC 驱动 jar 包(mysql-connector-java-8.0.xx.jar)复制进去,然后右键 jar 包选择Add as Library。这一步就是「idea怎么导入jar包」的标准操作,很多人卡在这里是因为只复制了文件没做Add as Library,结果编译时报ClassNotFoundException。

目录结构建议这样组织:

src/ com/bank/ entity/ // 实体类:User、Account、Transaction dao/ // 数据访问层:UserDao、AccountDao service/ // 业务逻辑层:BankService ui/ // 界面层:LoginFrame、MainFrame util/ // 工具类:DBUtil test/ // 测试入口:Main

分层不是为了好看,是为了让你在调试时能快速定位问题。界面报错找ui,数据不对找dao,业务规则错了找service。如果所有代码都堆在一个类里,改一个存取款的逻辑要翻三百行,血泪经验。

2.3 数据库建表:三张表撑起整个系统

在 MySQL 里建一个库bank_db,字符集用utf8mb4,然后执行下面的建表语句。这三张表是整个系统的地基,字段设计直接决定了后面业务逻辑好不好写。

CREATE DATABASE bank_db DEFAULT CHARACTER SET utf8mb4; USE bank_db; -- 用户表:登录用 CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, real_name VARCHAR(50), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 账户表:一个用户可以有多个账户 CREATE TABLE t_account ( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, card_no VARCHAR(20) NOT NULL UNIQUE, balance DECIMAL(15,2) DEFAULT 0.00, status TINYINT DEFAULT 1, -- 1正常 0冻结 FOREIGN KEY (user_id) REFERENCES t_user(id) ); -- 交易流水表:记录每一笔操作 CREATE TABLE t_transaction ( id INT PRIMARY KEY AUTO_INCREMENT, card_no VARCHAR(20) NOT NULL, type VARCHAR(20) NOT NULL, -- 存款/取款/转账 amount DECIMAL(15,2) NOT NULL, balance_after DECIMAL(15,2), target_card VARCHAR(20), trans_time DATETIME DEFAULT CURRENT_TIMESTAMP );

balance用DECIMAL(15,2)而不是FLOAT或DOUBLE,因为金额计算不能有浮点误差,这是金融类项目的铁律。t_transaction表里存了balance_after,这样查流水时不用再关联账户表算余额,直接读就行,查询效率高很多。

3. 从登录到转账:Swing 界面与 JDBC 的完整对接

3.1 登录界面:事件监听与数据库校验

登录界面是整个系统的入口,用JFrame加几个JLabel、JTextField、JPasswordField和JButton就能搭出来。关键不在界面长什么样,而在按钮的ActionListener里怎么把用户输入和数据库里的记录做比对。

// LoginFrame.java 核心逻辑 loginBtn.addActionListener(e -> { String username = usernameField.getText().trim(); String password = new String(passwordField.getPassword()).trim(); if (username.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(this, "用户名和密码不能为空"); return; } UserDao userDao = new UserDao(); User user = userDao.login(username, password); if (user != null) { this.dispose(); // 关闭登录窗口 new MainFrame(user).setVisible(true); // 打开主界面 } else { JOptionPane.showMessageDialog(this, "用户名或密码错误"); } });

UserDao.login方法里用PreparedStatement而不是Statement,这是防 SQL 注入的基本功。参数用?占位,然后ps.setString(1, username)依次赋值。很多人写课程设计时图省事用字符串拼接,结果输入' or '1'='1就能直接登录,这种代码放到简历里是减分项。

public User login(String username, String password) { String sql = "SELECT * FROM t_user WHERE username = ? AND password = ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, password); ResultSet rs = ps.executeQuery(); if (rs.next()) { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setRealName(rs.getString("real_name")); return user; } } catch (SQLException ex) { ex.printStackTrace(); } return null; }

DBUtil.getConnection()里把 URL、用户名、密码写死或者读配置文件都行,但要注意每次用完连接必须关闭。上面用了 try-with-resources,Connection和PreparedStatement会自动关闭,不用手动写finally块。这是 Java 7 之后的标准写法,比老教程里的finally关闭优雅得多。

3.2 主界面与账户操作:JTable 展示数据,事务保证一致性

主界面用JTabbedPane分几个标签页:账户信息、存款、取款、转账、交易流水。账户信息页用JTable展示当前用户的所有账户,数据从t_account表查出来塞进DefaultTableModel。

// 加载账户列表到表格 String[] columns = {"卡号", "余额", "状态"}; DefaultTableModel model = new DefaultTableModel(columns, 0); List<Account> accounts = accountDao.findByUserId(user.getId()); for (Account acc : accounts) { model.addRow(new Object[]{ acc.getCardNo(), acc.getBalance(), acc.getStatus() == 1 ? "正常" : "冻结" }); } accountTable.setModel(model);

存款和取款逻辑相对简单,就是更新t_account的balance字段,同时往t_transaction插一条记录。但转账不一样,它涉及两个账户的余额变动,必须放在一个数据库事务里,要么都成功,要么都回滚。

public boolean transfer(String fromCard, String toCard, BigDecimal amount) { Connection conn = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false); // 开启事务 // 扣款 String sql1 = "UPDATE t_account SET balance = balance - ? WHERE card_no = ? AND balance >= ?"; PreparedStatement ps1 = conn.prepareStatement(sql1); ps1.setBigDecimal(1, amount); ps1.setString(2, fromCard); ps1.setBigDecimal(3, amount); int rows1 = ps1.executeUpdate(); // 入账 String sql2 = "UPDATE t_account SET balance = balance + ? WHERE card_no = ?"; PreparedStatement ps2 = conn.prepareStatement(sql2); ps2.setBigDecimal(1, amount); ps2.setString(2, toCard); int rows2 = ps2.executeUpdate(); if (rows1 == 1 && rows2 == 1) { conn.commit(); return true; } else { conn.rollback(); return false; } } catch (SQLException e) { try { if (conn != null) conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } return false; } finally { try { if (conn != null) { conn.setAutoCommit(true); conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } }

扣款 SQL 里带了AND balance >= ?,这是防止余额不足时扣成负数。如果rows1返回 0,说明余额不够或者卡号不存在,直接回滚。conn.setAutoCommit(false)是事务的起点,commit()和rollback()是终点。注意在finally里要把autoCommit恢复成true再关闭连接,否则连接池复用时会出问题。

3.3 交易流水查询:条件筛选与分页思路

流水查询界面给用户一个卡号输入框和一个日期范围选择,点查询后从t_transaction表里捞数据。SQL 用WHERE card_no = ? AND trans_time BETWEEN ? AND ?,参数用PreparedStatement设置。

String sql = "SELECT * FROM t_transaction WHERE card_no = ? " + "AND trans_time BETWEEN ? AND ? ORDER BY trans_time DESC";

如果数据量大,可以加分页,用LIMIT ? OFFSET ?。课程设计阶段数据量小,不分页也能跑,但简历上写了分页会显得更完整。ORDER BY trans_time DESC让最新的交易排在最前面,符合用户习惯。

4. 避坑与排查:那些让课程设计卡三天的典型问题

4.1 连接 MySQL 报Public Key Retrieval is not allowed

现象:IDEA 里运行程序,控制台抛出javax.net.ssl.SSLException: java.security.cert.CertificateException或者Public Key Retrieval is not allowed。

原因:MySQL 8.0 默认使用caching_sha2_password认证插件,JDBC 驱动在连接时需要获取公钥,但默认不允许。

解决:在 JDBC URL 后面加上allowPublicKeyRetrieval=true&useSSL=false。完整 URL 类似jdbc:mysql://localhost:3306/bank_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false。serverTimezone不加也可能报时区错误,一并加上。

4.2 中文乱码:数据库、连接、界面三处都要统一

现象:界面上输入中文姓名,存进数据库变成???,或者查出来显示乱码。

原因:字符集不统一。数据库建库时没指定utf8mb4,JDBC URL 没加characterEncoding=utf8,Swing 组件没设置字体。

解决:建库语句写DEFAULT CHARACTER SET utf8mb4;JDBC URL 加useUnicode=true&characterEncoding=utf8;Swing 的JLabel、JButton如果显示中文方块,在main方法开头设置UIManager.setLookAndFeel为系统外观,或者手动给组件设setFont(new Font("微软雅黑", Font.PLAIN, 14))。

4.3ClassNotFoundException: com.mysql.cj.jdbc.Driver

现象:编译通过,运行时报找不到驱动类。

原因:jar 包没有真正加入 classpath。在 IDEA 里只把 jar 复制到lib目录不够,必须右键Add as Library,或者在Project Structure的Modules里把 jar 加到Dependencies。

解决:打开File -> Project Structure -> Modules -> Dependencies,点+号选JARs or directories,把lib下的驱动 jar 加进去,Scope 选Compile。加完后重新运行。

4.4 转账后余额不对:事务没生效或自动提交没关

现象:转账时扣了款但对方没收到,或者两边都加了钱。

原因:conn.setAutoCommit(false)没写,或者写了但commit()之前抛异常没回滚。

解决:确认转账方法里第一行就是conn.setAutoCommit(false),并且commit()和rollback()都在try-catch里成对出现。调试时可以在commit()前打断点,看两个executeUpdate的返回值是不是都是 1。

4.5 IDEA 运行报cannot start internal http server

现象:IDEA 启动项目时弹窗报cannot start internal http server,项目跑不起来。

原因:通常是 IDEA 内置服务器端口被占用,或者防火墙拦截。

解决:重启 IDEA;如果不行,在Settings -> Build, Execution, Deployment -> Debugger里把Built-in server port改成一个不常用的端口,比如 63342 改成 63343。这个报错和银行管理系统本身无关,是 IDEA 环境问题,别去改代码。

5. 进阶技巧:把课程设计改成能写进简历的项目

5.1 用 DAO 工厂 + 配置文件解耦

现在的DBUtil里数据库账号密码是写死的,换个环境就要改代码。进阶做法是建一个db.properties放在src目录下:

jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/bank_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false jdbc.username=root jdbc.password=123456

然后DBUtil用ClassLoader.getSystemClassLoader().getResourceAsStream("db.properties")加载。这样部署到别的机器上只需要改配置文件,不用重新编译。这个改动很小,但面试时提到「配置外置」是个加分点。

5.2 给关键操作加日志,排查问题不用猜

Swing 程序出问题时,控制台往往只有一行NullPointerException,根本不知道哪一步空了。在service层的关键方法入口加一行System.out.println或者用java.util.logging.Logger记录参数:

private static final Logger logger = Logger.getLogger(BankService.class.getName()); public boolean transfer(String fromCard, String toCard, BigDecimal amount) { logger.info("转账开始: from=" + fromCard + ", to=" + toCard + ", amount=" + amount); // ... 业务逻辑 logger.info("转账结束: result=" + result); return result; }

日志不用多,转账、存款、取款、登录这四个操作各加两条就够。出问题时看控制台输出,能快速定位是参数传错了还是 SQL 没执行。

5.3 用 JUnit 做 DAO 层单元测试

界面测试靠手点,但 DAO 层可以用 JUnit 自动测。在 IDEA 里新建一个test目录,标记为Test Sources Root,然后写:

@Test public void testTransfer() { BankService service = new BankService(); boolean result = service.transfer("6222020200112233", "6222020200112244", new BigDecimal("100.00")); assertTrue(result); // 验证余额 AccountDao dao = new AccountDao(); Account from = dao.findByCardNo("6222020200112233"); assertTrue(from.getBalance().compareTo(new BigDecimal("900.00")) == 0); }

跑一遍测试,比手动点十遍界面靠谱。而且简历上写「使用 JUnit 对 DAO 层进行单元测试」,比只写「实现了银行管理系统」有说服力得多。

5.4 打包成可执行 JAR,让演示不依赖 IDEA

课程设计答辩时,总不能现场打开 IDEA 跑。用File -> Project Structure -> Artifacts新建一个JAR -> From modules with dependencies,Main Class 选com.bank.test.Main,然后Build -> Build Artifacts生成 jar。生成的 jar 在out/artifacts目录下,双击就能运行(前提是目标机器装了 JDK)。如果想让没装 JDK 的机器也能跑,可以用jpackage打成 exe,但那是另一个话题了。

我自己的习惯是:每完成一个模块就打包一次,确保 jar 能跑起来。别等到答辩前一天才发现打包报错,那时候改配置的时间都不够。这个银行管理系统看着简单,但把环境、分层、事务、打包这几件事都走一遍,对 Java 桌面开发的理解会比看十篇教程都扎实。希望帮到你。

本文还有配套的精品资源,点击获取

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

SAP物料管理细分策略实操:从特性创建到后台配置的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 12:14:51

PJ85718DM远程温度传感器与STM32L4A6RG嵌入式测温方案设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 12:12:59

STM32F429ZI+PJ85718DM实现HVAC双点温度监测方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 12:12:59

基于单总线温度传感器与PIC18F的HVAC双轨监测系统设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 12:12:50

PJ85718DM与PIC18F85J10构建HVAC确定性温控边缘节点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 12:10:00

端侧推理选型指南:轻量模型差距缩至3%的部署实践

1. 端侧推理选型的核心矛盾与破局思路端侧推理这件事&#xff0c;做了几年下来最大的感受就是&#xff1a;模型能力与硬件资源之间永远在打架。你想让设备本地跑一个足够聪明的模型&#xff0c;但算力、内存、功耗三座大山压在那里&#xff0c;稍微大一点的模型就直接把设备拖垮…

作者头像 李华