尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

JavaWeb银行账目管理系统毕设指南:Servlet与JDBC实战

发布时间:2026/9/29 19:39:18

资讯中心
01
ARTICLE

JavaWeb银行账目管理系统毕设指南:Servlet与JDBC实战

JavaWeb银行账目管理系统毕设指南:Servlet与JDBC实战
简介基于JavaWeb技术栈的银行帐目管理系统毕业设计项目面向计算机相关专业正在准备毕设的学生以及需要项目实战练习的Java学习者。系统采用B/S结构后端基于JSP、Servlet、JDBC框架数据库使用MySQL开发环境涵盖JDK、Eclipse与Tomcat项目经过严格调试可确保直接运行。资源包共含3个文件包括项目源码、MySQL数据库脚本及项目说明文档整体大小仅1.24MB部署所需核心材料一应俱全。功能覆盖用户与管理员双角色包含帐户管理存款、取款、开户、销户、办卡、挂失卡、取款机信息管理、用户查询以及VIP统计、ATM业务量统计、消费统计等查询统计模块可作为完整毕设参考方案或课程设计项目使用。目前已有2301人学习浏览系统功能完善、界面简洁、操作便捷具有较高实际应用价值。1. JavaWeb银行帐目管理系统为什么是毕设的“安全牌”一个选题与落地的快照“基于JavaWeb的银行帐目管理系统【项目源码数据库脚本】(毕设)”这个标题每年都出现在各种源码包里它之所以常青不是因为技术新而是因为它把JavaWeb的核心链路——Servlet、JSP、JDBC、Session、Tomcat、MySQL——完整地串了一遍。它解决的问题非常具体毕设阶段需要一套能快速跑通、能讲清楚原理、能拿上台答辩的Web应用它适合的人也明确对JavaWeb还没有形成完整闭环、想用一套经典代码把从前端表单到后端数据库所有环节打通的同学。选题够老不等于没坑源码拿到手不是双击就能跑数据库脚本导入失败、Tomcat版本和IDEA配置不匹配都足够卡你一两天。这篇笔记按“拆结构、跑通、调JDBC、避坑、增强”的顺序把这条路的完整走法写给你。2. 拆开项目源码技术栈选型与三张核心表结构设计拿到一个JavaWeb毕设源码包第一步不是急着点运行而是先看清它用的是什么技术栈、业务模块分了几块、数据库表结构长什么样。这三件事直接决定你能不能跑起来、答辩时能不能讲明白。2.1 为什么还选ServletJSPJDBC而不是SpringBoot全家桶很多同学拿到源码包的第一反应是都什么年代了还在用Servlet毕设难道不该上SpringBoot这个想法在“做项目”的语境里是对的但在“毕设答辩”的语境里要打个问号。毕设考察的是你对JavaWeb核心知识的掌握程度ServletJSPJDBC这套组合恰好把HTTP请求到数据库访问的每一个环节都裸露出来Servlet处理请求、JSP渲染页面、JDBC操作数据库、Filter做编码过滤、Session管登录态。这些恰恰是SpringBoot帮你封装掉的部分。老师问“你的过滤器在哪”、“事务怎么控制的”、“Session什么时候失效”用这套老组合你能直接指到代码行用SpringBoot的话回答往往变成“自动配置的”这就失去了答辩的主动权。另外这套组合在源码包里“能跑通”的概率极高。ServletJSP项目对Tomcat版本、JDK版本的要求没那么苛刻Tomcat 8.5配JDK 8基本是标准组合。相比之下SpringBoot项目动不动就遇到依赖版本冲突、Maven仓库下载失败对毕设来说这些完全是额外风险。当然答辩时要会说一句话真实银行系统不会用JSP这里选ServletJSP是为了把JavaWeb的技术闭环完整显现出来。这句表态能让老师觉得你清楚工程实际和教学场景的区别。2.2 银行帐目管理系统的四个业务模块分别管什么不管源码包里的类名怎么起银行业务的核心模块逃不出下面这四块。你拿到的项目源码大概率是按照这个结构组织Servlet和JSP页面的。第一是登录与权限管理。系统有管理员和柜员两类角色登录后把用户对象放进Session每次请求通过Filter或Servlet基类校验登录态。这里要注意的是密码不能明文入库常见做法是MD5摘要后入库有的项目会给MD5加盐这在答辩时是一个加分细节。第二是账户管理。包括开户、销户、冻结、修改客户信息。开户时生成唯一账号初始余额一般设为0销户通常是逻辑删除把账户状态置为0而不是物理删除记录原因后面讲表结构时会提到。第三是存取款与转账。这是整个系统的核心。存款单账户加钱并写一条流水取款要判断余额是否充足转账涉及两个账户转出方扣款、转入方加款同时产生两条流水。转账是唯一必须上数据库事务的地方后续避坑章节会专门展开。第四是查询与报表。按账户查流水、按日期范围查交易汇总、打印当日账单。这个模块通常用一条带时间条件的SQL加一个分页就够是答辩演示用得最多的页面。2.3 数据库脚本里的三张核心表sys_user、account、trade_record数据库脚本是整个系统能不能跑起来的前提。我见过太多项目源码能编译但数据库脚本是SQL Server方言导入MySQL报错一堆。所以拿到脚本先认表结构下面这个建表方案是JavaWeb银行系统最常见的模板可以直接对照你的源码包。-- 系统用户表存登录系统的人不存银行客户 CREATE TABLE sys_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录名, password VARCHAR(64) NOT NULL COMMENT MD5摘要不要存明文, real_name VARCHAR(50) COMMENT 柜员真实姓名, role TINYINT DEFAULT 1 COMMENT 1-管理员 2-柜员, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表; -- 银行账户表一人可持多账户 CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, account_no VARCHAR(20) NOT NULL UNIQUE COMMENT 账号业务生成不靠自增, customer_name VARCHAR(50) NOT NULL COMMENT 客户姓名, balance DECIMAL(15,2) NOT NULL DEFAULT 0.00 COMMENT 余额禁止用double, status TINYINT DEFAULT 1 COMMENT 1-正常 0-冻结 2-销户, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT银行账户表; -- 交易流水表每一笔存取、转账留下痕迹 CREATE TABLE trade_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, account_id INT NOT NULL COMMENT 所属账户程序层关联account, trade_type TINYINT COMMENT 1-存款 2-取款 3-转入 4-转出, amount DECIMAL(15,2) NOT NULL COMMENT 交易金额恒为正数, balance_after DECIMAL(15,2) NOT NULL COMMENT 交易后余额用于对账, remark VARCHAR(255) COMMENT 备注可存对方账号, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_account_time (account_id, create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT交易流水表;这段SQL里最关键的设计是balance DECIMAL(15,2)和trade_record.balance_after。用DECIMAL而不是double是因为浮点数在二进制里无法精确表示十进制小数0.1加0.2在double下等于0.30000000000000004银行账目分毫不差是底线这个坑后面专门讲。balance_after记录每笔交易后的余额等于给每次余额变动留下快照答辩时说“可以用它做全链路对账”比单纯说“我建了流水表”高一个层次。另一个细节是三张表之间我没有写物理外键。这不是偷懒而是毕设项目里物理外键的收益很低、坑很多销户时如果有流水子记录外键约束会挡住删除修改主键ID时也要连带修改子表。常见做法是在应用层维护逻辑关联trade_record.account_id指向account.id但不建FOREIGN KEY。这个取舍答辩时也可以主动讲老师通常认可。3. 用IDEA跑通源码从导入项目到Tomcat启动的六个步骤源码包到手最急迫的问题是“怎么在IDEA里跑起来”。这个环节翻车率最高但翻车点非常集中基本集中在项目识别、Artifact配置和Tomcat版本三个地方。按下面六步走能避掉八成问题。3.1 拿到源码包先看这四处避免盲猜不要解压后直接双击.iml或.idea文件让IDEA打开那样经常导入成普通Java项目Web目录识别不了。我一般先解压然后用文件管理器看四样东西。第一是README或部署文档里面通常写了数据库用户名密码、MySQL版本、Tomcat版本、JDK版本。第二是sql目录看脚本第一行是MySQL的CREATE DATABASE还是SQL Server的IF NOT EXISTS这决定你后面能不能顺利导入。第三是web/WEB-INF/web.xml看servlet-version是多少、有没有配置welcome-file、有没有过滤器。第四是源码目录里有没有残留的out或target文件夹有的话建议先删掉防止IDEA识别到旧的编译产物。一个常见坑是解压出双层目录比如BankAccountSys-master/BankAccountSys导入时选错层级会导致后面所有路径对不上。建议先把目录改名成无中文、无空格的BankAccountSys放到一个路径里没有中文的目录下。中文路径在Tomcat部署时偶尔会触发奇怪的静态资源404属于玄学问题提前规避。下面是这个类型项目最常见的目录骨架你可以对照自己的源码包看缺了什么。BankAccountSys/ ├── src/ │ └── com/edu/bank/ │ ├── servlet/ # 所有Servlet控制器 │ ├── dao/ # JDBC数据访问层 │ ├── service/ # 业务逻辑层 │ ├── utils/ # DBUtil、MD5工具类 │ └── model/ # 实体类 ├── web/ │ ├── WEB-INF/ │ │ ├── web.xml # 部署描述符 │ │ └── lib/ # mysql-connector-java.jar 必须在这 │ ├── css/ │ ├── js/ │ └── *.jsp ├── sql/ │ └── bank.sql # 数据库脚本 └── README.md判断这个骨架是否完整的关键是web/WEB-INF/lib下有没有mysql-connector-java.jar。这个jar是连接MySQL的桥梁很多项目源码里没带需要你自己下载对应版本放进去否则后面会报ClassNotFoundException。3.2 IDEA导入JavaWeb项目的两种方式与Web目录识别在IDEA里导入有两种常见操作。第一种也是我推荐的方式File New Project from Existing Sources选中解压后的根目录IDEA会弹出导入向导。如果你是Maven项目就选Maven但这个技术的毕设项目绝大多数不是Maven直接选Next到底让IDEA自动识别src为Sources Root、web为Web Resource Directory。第二种方式是File Open直接打开然后手动进Project Structure Modules调整。这种方式容易漏配Web资源目录导致JSP页面找不到我不太建议新手用。导入完成后打开Project Structure Project确认三件事SDK是JDK 8或11Language Level设为8Modules的Web页签里能看到web目录被标记为Web Resource Directory。这三项不对后面编译和部署都会出幺蛾子。如果项目里带着.class文件建议先在Build Rebuild Project前把它们清理干净防止旧的字节码覆盖新编译结果。这个操作虽小但能避免很多“我改了代码没生效”的灵异事件。3.3 Tomcat部署参数Artifact、context path和端口项目导入成功后接着配置Tomcat运行环境。先确认你本地装了Tomcat 8.5或9.x然后按下面的顺序操作。Run Edit Configurations点左上角加号选择Tomcat Server Local。在Application server那里选中你本地的Tomcat目录。如果下拉框是空的说明IDEA没识别到Tomcat需要先Settings Build, Execution, Deployment Application Servers手动添加Tomcat路径。切到Deployment页签点加号选Artifact弹出的列表里选择xxxx:war exploded。这里有两个关键点选exploded而不是warexploded表示解压目录部署改动Java代码后热更新更快毕设调试阶段用这个合适Application context建议填成/bank这样访问路径是http://localhost:8080/bank/login.jsp如果留空或填/会把Tomcat根路径整个占掉和Tomcat自带应用冲突。启动前顺手把三个参数调好见下表配置项推荐值说明VM options-Dfile.encodingUTF-8防止运行时读取资源文件中文乱码On Update ActionUpdate classes and resources改Java/JSP后能快速生效On Frame DeactivationUpdate classes and resources切走窗口时自动更新资源HTTP port8080或80818080被占用时换8081并检查是否有残留进程点Debug启动控制台出现Connected to server基本就算成功了一半。然后验证HTTP服务是否真的通了用下面的命令检查# 在终端验证Tomcat是否返回HTTP 200 curl -I http://localhost:8080/bank/login.jsp如果返回HTTP/1.1 200说明项目和Tomcat已经打通如果404先看是不是Application context填错了再看web.xml里的欢迎页配置。这一步能帮你把“IDEA问题”和“项目问题”分开排查。4. 让数据库脚本说话导入bank.sql并打通JDBC数据链路Tomcat能启动只是表象真正让系统“活”起来的是数据库。JavaWeb银行系统里几乎每个页面后面都站着至少一条SQL。数据库脚本导入不成功、JDBC连接参数不对系统就是一个空壳。4.1 执行bank.sql的两种方式Navicat与命令行拿到bank.sql先看里面有没有CREATE DATABASE语句。很多脚本开头自己建库有些则不建需要你手动先建好库再导入。用Navicat的话操作路径是连接MySQL后新建一个数据库名字要和脚本里的USE xxx一致或者和JDBC URL里的库名一致然后右键这个库选择运行SQL文件。弹窗里记得把编码选成UTF-8这个选项在Navicat里容易被忽略选错会出现中文乱码或建表失败。用命令行的话可以分两步执行。先建库并设置字符集再导入脚本# 建库指定utf8mb4字符集 mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS bank_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 导入脚本 mysql -uroot -p bank_db sql/bank.sql逻辑说明-uroot是用户名-p会提示输入密码bank_db是目标数据库名表示把文件内容喂给mysql客户端执行。参数说明DEFAULT CHARACTER SET utf8mb4这一步很关键。如果建库时用了默认的latin1后面中文数据一律乱码而且再改库字符集也救不回已经插入的乱码数据。脚本路径建议用绝对路径或先cd到项目根目录再执行避免路径解析出错。导入成功的标准不是“没有报错”而是库里真的有三张表。用SHOW TABLES;确认再用DESC trade_record;看amount字段类型是不是DECIMAL(15,2)。如果你用的IDEA也可以在下方的Database面板里右键数据库导出脚本但本地开发阶段不会用这个操作它更适合交作业时生成一份干净的bank.sql。4.2 JDBC连接参数逐个调MySQL8.0的四个必填参数很多项目代码里自带一个DBUtil.java或JdbcUtils.java封装了数据库连接逻辑。拿到手别急着运行先看连接参数是不是匹配你本机的MySQL版本。下面是兼容MySQL 8.0的标准写法public class JdbcUtils { private static final String DRIVER com.mysql.cj.jdbc.Driver; private static final String URL jdbc:mysql://localhost:3306/bank_db ?useUnicodetruecharacterEncodingutf8 useSSLfalse serverTimezoneAsia/Shanghai allowPublicKeyRetrievaltrue; private static final String USER root; private static final String PASSWORD 你的密码; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { throw new RuntimeException(MySQL驱动jar未找到, e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }逻辑说明Class.forName是加载驱动类MySQL 8.0之后的驱动类名是com.mysql.cj.jdbc.Driver旧版的是com.mysql.jdbc.Driver。如果你的项目用的是旧类名同时装的是新驱动一样会报ClassNotFoundException。参数说明serverTimezoneAsia/Shanghai是为了规避MySQL 8.0要求显式指定时区的报错useSSLfalse在本地开发时关闭SSL握手既省时间又避免警告characterEncodingutf8配合useUnicodetrue保证中文写入不乱码allowPublicKeyRetrievaltrue是给MySQL 8.0默认的caching_sha2_password认证插件用的不设置时偶尔会报Public Key Retrieval is not allowed。密码里的特殊字符也要注意比如密码是abc123这个在URL里会被解析成参数分隔符必须写成abc%40123。这不是JDBC的锅而是URL语法本身的规定。4.3 从登录到查流水一条SQL如何走完MVC链路连接打通后用登录这个最基础的功能看一遍数据是怎么流动的。用户在前端输入用户名密码表单POST到LoginServletServlet拿到参数调用DAO层DAO用PreparedStatement执行SQL结果封装成User对象存在Session里跳转页面。这段代码是DAO层查询用户的核心public User findByUsernameAndPassword(String username, String passwordMd5) { String sql SELECT id, username, real_name, role FROM sys_user WHERE username ? AND password ?; try (Connection conn JdbcUtils.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, passwordMd5); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { User u new User(); u.setId(rs.getInt(id)); u.setUsername(rs.getString(username)); u.setRealName(rs.getString(real_name)); u.setRole(rs.getInt(role)); return u; } } } catch (SQLException e) { e.printStackTrace(); } return null; }逻辑说明PreparedStatement的?占位符由setString传入底层做了参数化处理天然防止SQL注入。写WHERE username username这种字符串拼接的项目在答辩时等于送分给老师抓。参数说明Password存的是MD5摘要不是明文所以这里传入的是passwordMd5。校验逻辑是把用户输入的密码做一次MD5再比对而不是把数据库里的密文解回明文。这里常见的做法是给MD5加盐即md5(username 固定的盐 password)能有效挡掉彩虹表碰撞源码包里如果没做盐你可以自己补上这是低成本加分项。Servlet层的登录处理和跳转也有讲究WebServlet(/login) public class LoginServlet extends HttpServlet { private UserDao userDao new UserDao(); protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String username req.getParameter(username); String password req.getParameter(password); User user userDao.findByUsernameAndPassword(username, MD5Utils.md5(password)); if (user ! null) { req.getSession().setAttribute(loginUser, user); resp.sendRedirect(req.getContextPath() /main.jsp); } else { req.setAttribute(errorMsg, 用户名或密码错误); req.getRequestDispatcher(/login.jsp).forward(req, resp); } } }逻辑说明登录成功用sendRedirect重定向失败用forward转发。区别在于转发是服务器内部跳转地址栏不变request域的errorMsg还能带到JSP页面上重定向是浏览器重新发起一次GET请求request域里的值会丢但能避免用户刷新页面时表单重复提交。这两个动作的语义区别是JavaWeb必考题。参数说明req.setCharacterEncoding(UTF-8)必须放在第一次调用getParameter之前否则POST请求的中文参数还是乱码。如果你在过滤器里统一处理了编码这里可以省略但一定要保证过滤器在web.xml中的url-pattern覆盖/login。5. 毕设级避坑手册五个最容易翻车的JavaWeb现场跑通和跑好之间隔着几个经典坑。这些坑我几乎在每个JavaWeb项目里都见过有的能快速定位有的会让你怀疑是编码问题还是Tomcat坏了。按“现象、原因、解决”挨个说。5.1 登录页能打开但跳转404web.xml和context path的事现象启动正常访问login.jsp正常但输入账号密码提交后浏览器报404。原因通常不是Servlet代码错了而是三个地方没对上。第一表单的action路径和WebServlet的映射不一致第二web.xml里没有配置welcome-file或者配置了但文件名写错第三部署时Application context填了/bank但页面里写的跳转地址是/login而不是/bank/login。解决先在浏览器地址栏手动访问http://localhost:8080/bank/login看Servlet本身通不通。如果手动通而表单提交不通问题在表单action。如果手动访问Servlet返回404问题在Servlet映射或web.xml。再顺手检查一下IDEA控制台有没有Invalid mapping之类的启动警告这个警告会直接告诉你是哪个Servlet路径没注册上。另外有个排查习惯每次改了web.xml或Servlet注解必须重启Tomcat热部署在这里不总是生效。如果改完还是404用Build Rebuild Project强制刷新一下很多时候是IDEA没重新编译。5.2 数据库连不上ClassNotFound、Access denied、Communications link failure现象启动后访问查询页面页面报500控制台刷出一堆异常堆栈。原因这个坑其实是三个不同的现象盖在一顶帽子里。先看堆栈最底行写的是什么。ClassNotFoundException: com.mysql.cj.jdbc.Driver说明驱动jar没进WEB-INF/lib或者IDEA的Libraries里没引用。解决方式把jar直接复制到web/WEB-INF/lib下然后在Project Structure Libraries里确认它被当前Module引用重启Tomcat。Access denied for user rootlocalhost说明用户名、密码或权限不对。先手动在命令行里mysql -uroot -p试试能不能连上能连上说明密码没问题那就要看URL里的密码有没有被特殊字符坑了。密码含、、#都会出问题最省事的做法是把密码改成纯字母数字。Communications link failure或The server time zone value这俩本质是JDBC URL参数问题。serverTimezoneAsia/Shanghai必填MySQL 8的用户建议把allowPublicKeyRetrievaltrue也加上。端口也要看MySQL默认3306如果你本机装的是MariaDB或者改了端口URL里的3306要改。5.3 中文乱码POST、GET和响应输出三个方向不一样现象注册的客户姓名在页面上显示成“???”或者存入数据库后变成“å§æ”。原因Java里中文乱码的来源极其统一——字符从A编码写进去被B解码读出来。POST和GET的处理方向还不一样。POST请求看的是request.setCharacterEncoding(UTF-8)有没有在读取参数前执行GET请求看的是Tomcat连接器解码URI时用的字符集Tomcat 8.0之后默认UTF-8所以问题少但老项目配Tomcat 7就要改server.xml里的URIEncodingUTF-8。解决写一个过滤器统一处理比在每个Servlet里重复设置靠谱得多WebFilter(/*) public class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; if (request.getMethod().equalsIgnoreCase(POST)) { request.setCharacterEncoding(UTF-8); } resp.setCharacterEncoding(UTF-8); resp.setContentType(text/html;charsetUTF-8); chain.doFilter(req, resp); } }逻辑说明WebFilter(/*)代表拦截所有请求POST请求在读参数之前统一设置请求编码响应统一设置为UTF-8。注意setCharacterEncoding必须在getParameter之前调用放到过滤器里就是为了保证这个顺序。参数说明如果项目是旧式web.xml配置过滤器顺序很重要——过滤器声明顺序就是执行顺序编码过滤器要放在其他过滤器前面。另外JSP文件头部的pageEncoding和contentType也要写成UTF-8这属于页面静态编码过滤器管不到。5.4 转账后只有一条流水事务在哪里失效了现象转账功能填完金额点提交转出方扣了钱转入方没到账流水表里只有一条取款记录日志里没有任何异常。原因这个现象我在好几个项目里见过根子在于事务边界被切碎了。很多DAO类里的每个方法自己调JdbcUtils.getConnection()拿连接然后自己commit自己close。这样转出方DAO提交了转入方DAO虽然失败回滚但转出方已经提交成功留在数据库里。每一个数据库连接是独立事务想让两条更新成为同一个事务就必须让它们用同一个连接。解决事务应该放在Service层统一控制连接在Service层创建并作为参数传给DAO的方法Connection conn JdbcUtils.getConnection(); try { conn.setAutoCommit(false); // 扣款条件里带 balance ? 可以防超扣 int c accountDao.decreaseBalance(conn, fromId, amount); if (c ! 1) { conn.rollback(); throw new RuntimeException(余额不足); } // 加款 accountDao.increaseBalance(conn, toId, amount); // 写两条流水 tradeDao.insert(conn, fromId, 4, amount); // 转出 tradeDao.insert(conn, toId, 3, amount); // 转入 conn.commit(); } catch (Exception e) { conn.rollback(); throw e; } finally { conn.setAutoCommit(true); conn.close(); }逻辑说明setAutoCommit(false)之后后面所有SQL都在同一个事务里直到commit()或rollback()。decreaseBalance返回受影响行数如果为0说明条件没满足比如余额不足或账户不存在直接回滚。注意DAO接口里凡是涉及这个事务的方法都不能再自己调getConnection()必须接收外部传入的Connection。这是“事务跨方法”的典型写法也是黑马JavaWeb笔记里反复强调的那个点。答辩时能主动说出“我用Service层控制事务边界”这句话比写十页PPT管用。5.5 金额四舍五入差一分余额字段别用double现象每日流水汇总后页面显示的总金额和数据库里逐笔累加的结果差几分钱经常是出现一长串小数比如1586.2300000000001。原因double是浮点数二进制无法精确表示0.1累计运算次数多了误差就会暴露。银行系统的金额是十进制精确量用double等于埋雷。解决数据库层用DECIMAL(15,2)Java层用BigDecimal。查询结果用getBigDecimal取出运算用add、subtract不要用、-。金额计算示例如下BigDecimal balance rs.getBigDecimal(balance); BigDecimal amount new BigDecimal(100.00); BigDecimal newBalance balance.subtract(amount).setScale(2, RoundingMode.HALF_UP);逻辑说明BigDecimal构造建议传字符串new BigDecimal(0.1)会把二进制浮点误差一起带进来相当于白转。setScale(2, RoundingMode.HALF_UP)做的是四舍五入到两位小数这是账户金额显示的标准规则。参数说明页面显示金额时也不要随手doubleValue()转成String输出。如果项目里还有金额字段用float的一律改成DECIMAL。这个坑在银行题目里几乎是必考的改一处就少一个答辩软肋。6. 从“能跑”到“能答辩”三个低成本增强点系统能跑通只是及格线。想在答辩时让老师觉得“这个系统不是抄的”在原有代码上补三个增强点性价比最高。这三个点都不需要换技术栈也不需要引入Spring用现有ServletJDBC就能做。第一个是流水查询分页。很多源码包里的查询是SELECT * FROM trade_record数据一多页面直接卡死。改成LIMIT ?, ?秒级见效先查SELECT COUNT(*) FROM trade_record WHERE account_id ?拿总数再查当前页数据LIMIT的两个参数用setInt传不能拼进SQL字符串。顺带加一个ORDER BY create_time DESC按时间倒序展示客户看账单的体验完全不一样。第二个是当日交易汇总导出。不用上POI那套重依赖导出CSV是更轻的路线。设置响应头response.setHeader(Content-Disposition, attachment;filenamedaily.csv)输出流里指定GBK编码因为Excel用GBK打开CSV才不乱码。字段里如果含逗号或换行要加双引号转义这是一行代码级别的细节但能看出你考虑过真实导出场景。第三个是余额对账SQL。这是我觉得整个系统里最“银行”的一个功能——用流水表倒推账户余额跟账户表里的余额比对SELECT a.id, a.account_no, a.balance, (SELECT t.balance_after FROM trade_record t WHERE t.account_id a.id ORDER BY t.id DESC LIMIT 1) AS last_balance FROM account a HAVING a.balance last_balance;逻辑说明balance_after存的是每笔交易后的余额取最近一笔的balance_after理论上应该等于当前余额。如果两边对不上说明存在手工改数据或者事务丢失的情况。这个查询一出老师能直观看到表结构设计的伏笔比你自己介绍十句“我做了对账功能”都有效。我这些年带毕设的一个习惯是拿到任何源码包先让数据库脚本跑通再让项目在Tomcat里起来最后才开始读代码。数据库不通项目就是一幅空壳项目能跑再谈改业务。只要你把这三张表和一条转账链路摸透了这个选题就没有什么黑匣子可言。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。