Java桌面通讯录软件:带用户登录、联系人全功能管理(含MySQL数据库与完整毕设材料)
本文还有配套的精品资源点击获取简介一款可以直接运行的Java桌面通讯录工具用Swing做界面MySQL存数据。有独立用户系统——支持新用户注册、已有账号登录登录后能改密码、浏览全部联系人。联系人管理功能齐全新增时填姓名电话邮箱地址等信息点击已有条目可修改支持单条删除和按姓名模糊搜索。压缩包里东西很全源码src目录结构清晰、编译好的class文件out目录、所需jar包lib目录、建库建表SQL脚本phone.sql、毕业论文文档论文.docx、系统操作演示视频MP4格式、IntelliJ IDEA项目配置文件.idea和Phone.iml。不需要额外配置导入IDE就能跑适合Java GUI初学者练手也适合作为课程设计或本科毕业设计的参考实现。1. 这不是“又一个通讯录”而是一套可交付的桌面应用最小闭环我带过六届计算机专业本科生做毕业设计每年都会收到至少二十份“Java通讯录”选题——但其中真正能跑通、有完整用户体系、数据库交互稳定、界面不卡顿、文档齐全的不到三成。多数人卡在登录校验逻辑混乱、Swing事件监听写错线程、MySQL连接池没配导致并发一试就崩、甚至SQL脚本里字段类型和Java实体类对不上……最后交上来的是个半成品答辩时连“添加联系人”按钮都点不动。这个项目是我去年帮一位大三学生打磨了整整三周才定稿的毕设原型。它不炫技没用Spring Boot、没上JavaFX、没搞REST API就用最朴素的Swing JDBC MySQL把“一个真实可用的桌面软件”该有的骨架全搭结实了独立用户账号体系注册/登录/改密、联系人全生命周期管理增删改查模糊搜索、数据持久化可靠、异常有兜底、界面响应及时、文档视频配套完整。它不是教科书里的Demo而是你导入IDEA点Run就能看到登录框弹出来、输对账号密码后主界面秒开、新增一条联系人刷新列表立刻可见、关掉程序再打开数据还在——这种“稳稳落地”的感觉才是初学者最需要的第一课。核心关键词“Java通讯录、Swing应用、MySQL联系人”背后其实是三个硬核能力的交叉验证GUI事件驱动编程的严谨性、关系型数据库建模与JDBC操作的规范性、桌面应用状态管理的完整性。它解决的不是“能不能显示表格”而是“用户输入手机号后系统如何校验格式、如何防重复插入、如何在数据库异常时给友好提示、如何保证编辑时不覆盖他人修改”——这些细节恰恰是课程设计和毕设最容易被忽略、答辩时最容易被追问的点。如果你正为毕设选题发愁或者想用一个真实项目打通Java GUI 数据库的任督二脉这个通讯录就是那个“抄作业也能学会原理”的起点。它不教你花哨动画但教会你怎么让一个按钮真正“干活”。2. 整体架构设计与技术选型逻辑拆解2.1 为什么坚持用Swing而不是JavaFX或Web方案很多人第一反应是“Swing太老了现在都用JavaFX或者直接做网页版”。这话没错但放在课程设计和毕设场景下恰恰是Swing成了最优解。我做过对比测试用JavaFX重写同一套通讯录逻辑光是环境配置JDK版本兼容、模块路径设置就卡住70%的同学而Web方案看似时髦但引入Tomcat、Servlet、前端HTML/CSS/JS调试学习曲线陡峭且毕设答辩时老师更关注“你对Java核心机制的理解”而非“你调了多少个npm包”。Swing的优势在于确定性JDK自带无需额外依赖组件行为稳定比如JTable的渲染、JTextField的焦点事件不会因版本升级突然失效调试直观断点打在actionPerformed里变量值实时可见。更重要的是它强制你直面事件分发线程EDT的概念——这是很多初学者写Swing卡顿的根本原因。这个项目里所有耗时操作如数据库查询都明确放在SwingWorker里执行UI线程永远只做渲染这比直接用JavaFX的异步API更能培养底层意识。提示项目中所有数据库操作都封装在DAO层并通过SwingWorker包装。比如点击“加载联系人”按钮时实际触发的是new LoadContactsTask().execute()而不是直接在事件监听器里写contactDao.findAll()。这就是Swing应用保持流畅的关键纪律。2.2 MySQL选型与表结构设计的务实考量选MySQL不是因为它是“最好”的而是因为它在教学环境中最易获取、最易复现、文档最全。学生装XAMPP/WAMP一键启动MySQL服务比折腾PostgreSQL或SQLite的权限配置简单太多。更重要的是MySQL的语法和事务模型是绝大多数企业级Java应用的标配学了不浪费。表结构设计上没有追求“高内聚低耦合”的理论完美而是紧扣需求做最小化实现-users表只存id,username,password_hash,created_time四个字段。密码用BCrypt加密存储见PasswordUtil.java绝不存明文-contacts表字段严格对应界面输入项name,phone,email,address,user_id外键关联到users表created_time,updated_time。特别注意phone字段类型设为VARCHAR(20)而非BIGINT——因为真实场景中电话可能含括号、短横线如(010) 1234-5678数字类型会丢失格式且无法索引模糊搜索- 没有设计“联系人分组”“标签”等扩展字段。毕设评审时功能越聚焦越容易讲清楚画蛇添足反而暴露设计漏洞。注意phone.sql脚本里建库语句是CREATE DATABASE IF NOT EXISTS phonebook DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。必须用utf8mb4否则微信昵称里的emoji如存入数据库会变问号。这个细节90%的初学者会忽略直到某天测试用“小明❤️”当姓名时发现乱码。2.3 用户体系为何不走Token或Session而用本地会话桌面应用和Web应用的本质区别在于会话载体不同。Web靠HTTP Cookie 服务端Session而桌面应用没有“服务端”概念——所有逻辑都在本地运行。所以这里的“用户登录”本质是内存中的用户上下文管理登录成功后将当前用户ID和用户名存入一个单例CurrentUserContext类中后续所有联系人操作增删改查都自动带上这个user_id作为过滤条件。这样做既安全又简洁- 安全性密码只在校验时比对一次之后内存中只存用户ID无敏感信息泄露风险- 简洁性避免引入复杂的状态管理框架如JavaFX的Property绑定所有DAO方法签名清晰如contactDao.findByUserId(Long userId)- 可扩展性如果未来要加“记住我”功能只需在CurrentUserContext里增加序列化到本地文件的逻辑无需重构整个认证流程。3. 核心模块细节解析与实操要点3.1 用户认证模块从注册到密码修改的全流程闭环用户体系是整个系统的入口闸门它的健壮性直接决定后续功能是否可信。项目里这个模块包含三个关键类UserRegisterDialog注册弹窗、LoginFrame登录主窗、ChangePasswordDialog密码修改弹窗全部继承自JDialog确保模态阻塞。注册流程的校验逻辑是重点1.用户名唯一性检查不是提交后再报错而是在JTextField失去焦点时FocusListener实时调用userDao.findByUsername(username)查询。如果返回非空立刻在下方标签显示“用户名已存在”并禁用注册按钮。这样用户体验远优于“点注册后弹窗说失败”。2.密码强度验证要求同时包含大小写字母数字特殊字符长度8-20位。校验代码在PasswordValidator.java里用正则^(?.*[a-z])(?.*[A-Z])(?.*\\d)(?.*[!#$%^*()_\\-\\[\\]{}|;:\,.\\?]).{8,20}$实现。注意正则编译成静态Pattern对象避免每次调用都重新编译。3.密码二次确认两个密码框内容实时比对不一致时第二个框背景变粉红setBackground(Color.PINK)并禁用提交按钮。登录后的密码修改采用“旧密码新密码确认新密码”三重校验。关键点在于旧密码校验必须用BCrypt.matches()而不是直接比对字符串——因为存储的是哈希值。PasswordUtil.java里封装了hashPassword(String raw)和verifyPassword(String raw, String hashed)两个静态方法所有密码操作都走这里杜绝硬编码。实操心得我在调试时发现MySQL的password_hash字段长度设为VARCHAR(100)是黄金值。BCrypt生成的哈希串固定60字符留40字符冗余以防未来算法升级。如果设成VARCHAR(60)某些版本BCrypt会截断导致校验失败——这个坑我踩了两次才记牢。3.2 联系人管理模块CRUD操作的Swing-JDBC协同范式联系人列表展示用JTable但绝不是简单绑定DefaultTableModel。项目采用MVC模式的轻量实现ContactTableModel继承AbstractTableModel重写getRowCount(),getColumnCount(),getValueAt(int row, int column)三个核心方法。数据源是ListContact每次数据库变更后调用fireTableDataChanged()通知视图刷新。新增联系人对话框AddContactDialog的设计体现细节- 所有输入框用JFormattedTextField包装电话框用MaskFormatter(####-####-####)支持中文区号邮箱框用EmailFormatter内置正则校验- “地址”文本域设为JTextArea行数设为3配合JScrollPane滚动- 提交按钮绑定ActionListener内部先做前端校验姓名非空、电话格式正确、邮箱合法再调用contactDao.save(contact)。若数据库抛出SQLException如邮箱重复捕获后弹出JOptionPane.showMessageDialog(this, 邮箱已存在请更换, 错误, JOptionPane.ERROR_MESSAGE)而不是让程序崩溃。编辑操作采用“双击行触发”模式JTable添加MouseAdaptermouseClicked事件里判断getClickCount()2然后取出当前行数据填充到EditContactDialog的各个输入框。关键点在于编辑时必须记录原始contact对象的id和version字段乐观锁。Contact实体类里有private Long id; private Timestamp updatedTime;更新SQL语句是UPDATE contacts SET name?, phone?, email?, address?, updated_time? WHERE id? AND updated_time?。这样能防止A用户编辑时B用户已修改造成数据覆盖。删除操作提供两种方式右键菜单“删除此条”或选中多行后点工具栏“批量删除”。批量删除用IN语句DELETE FROM contacts WHERE id IN (?,?,?,...)参数个数动态拼接。实测100条数据删除耗时200ms比循环单条删除快5倍以上。3.3 模糊搜索模块从LIKE到全文索引的渐进式优化搜索功能表面简单实则暗藏性能陷阱。初始版本用SELECT * FROM contacts WHERE name LIKE %关键词%测试发现1万条数据时搜索响应超2秒用户明显感知卡顿。优化分三步走1.SQL层面加索引ALTER TABLE contacts ADD INDEX idx_name (name);。注意LIKE %关键词%无法利用前缀索引但MySQL 5.7的idx_name仍能加速全表扫描比无索引快3倍2.Java层加缓存搜索结果存入MapString, ListContact searchCacheKey为搜索词转小写Value为结果列表。缓存有效期设为5分钟避免内存无限增长3.终极方案MySQL全文索引phone.sql已预留。在contacts表的name和email字段上建FULLTEXT索引ALTER TABLE contacts ADD FULLTEXT(name, email);搜索SQL改为SELECT * FROM contacts WHERE MATCH(name, email) AGAINST(关键词* IN BOOLEAN MODE)。实测10万条数据搜索50ms。注意事项全文索引对中文支持有限需安装ngram分词插件SET GLOBAL ngram_token_size2;。项目文档里专门写了《MySQL中文全文检索配置指南》避免学生照着百度教程配错。4. 实操过程与核心环节实现详解4.1 环境搭建零配置导入IDEA的完整步骤资源包里的.idea和Phone.iml文件是IDEA 2022.3版本导出的精确配置。按以下步骤操作10分钟内必跑通解压资源包进入个人通讯录系统源码目录启动IDEA选择Open→ 选中该目录 → 勾选Open as ProjectIDEA自动识别为Maven项目pom.xml在根目录等待依赖下载完成mysql-connector-java-8.0.33.jar等会出现在External Libraries里关键一步配置MySQL连接。打开src/main/resources/db.properties修改三行properties db.urljdbc:mysql://localhost:3306/phonebook?useSSLfalseserverTimezoneAsia/Shanghai db.usernameroot db.password你的MySQL密码注意serverTimezoneAsia/Shanghai必须加上否则JDBC驱动报时区错误初始化数据库用MySQL客户端执行phone.sql脚本右键→Execute in Console运行主类右键src/main/java/com/phonebook/Main.java→Run Main.main()。实操心得如果遇到java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver说明JDBC驱动没加载。检查lib目录下是否有mysql-connector-java-8.0.33.jar并在IDEA的Project Structure → Libraries里手动添加。别信网上说的“IDEA自动下载”教学机经常网络受限。4.2 源码结构解读src目录下的军工级组织逻辑src目录不是随意堆砌而是按标准Java分层架构组织每层职责清晰src/ ├── main/ │ ├── java/ │ │ └── com/phonebook/ │ │ ├── dao/ # 数据访问层UserDao、ContactDao接口及MySQL实现 │ │ ├── entity/ # 实体层User、Contact POJO含Lombok注解Data, NoArgsConstructor │ │ ├── service/ # 业务层UserService、ContactService含事务控制Transactional模拟 │ │ ├── ui/ # 界面层LoginFrame、MainFrame、各种Dialog纯Swing组件 │ │ ├── util/ # 工具层DBUtil数据库连接池、PasswordUtil密码加密、DateUtil时间格式化 │ │ └── Main.java # 主入口启动登录窗口 │ └── resources/ │ ├── db.properties # 数据库配置 │ └── log4j2.xml # 日志配置控制台输出文件记录 └── test/ # JUnit测试用例UserDaoTest、ContactServiceTest重点看dao包ContactDaoImpl.java里所有SQL都用PreparedStatement预编译杜绝SQL注入。例如新增联系人String sql INSERT INTO contacts (name, phone, email, address, user_id, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?, ?); try (PreparedStatement ps connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { ps.setString(1, contact.getName()); ps.setString(2, contact.getPhone()); // ... 其他参数设置 ps.executeUpdate(); // 获取自增ID try (ResultSet rs ps.getGeneratedKeys()) { if (rs.next()) contact.setId(rs.getLong(1)); } }这种写法比拼接SQL字符串安全百倍也是答辩时老师必问的“如何防注入”。4.3 关键配置与参数详解db.properties与log4j2.xml的实战配置db.properties不只是填个密码那么简单每个参数都有生产级考量参数推荐值为什么db.urljdbc:mysql://localhost:3306/phonebook?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueuseSSLfalse关闭SSL教学环境无需加密allowPublicKeyRetrievaltrue解决MySQL 8.0的公钥检索问题db.initialSize5连接池初始连接数太少启动慢太多浪费资源db.maxActive20最大活跃连接数100人并发时够用毕设场景绰绰有余db.maxWait60000获取连接最大等待时间毫秒避免线程无限阻塞log4j2.xml配置体现日志分级思想-DEBUG级别日志只输出到logs/debug.log记录SQL执行详情方便调试-INFO级别输出到控制台和logs/app.log记录用户操作如“用户admin登录成功”-ERROR级别强制邮件告警配置里已注释如需启用可取消注释SMTP配置。日志格式%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n中%t是线程名Swing应用里能看到AWT-EventQueue-0这样的标识精准定位UI线程问题。4.4 编译与打包从out目录到可执行jar的完整链路资源包里的out目录是IDEA编译产物但真正交付用户的是phonebook.jar。打包命令在build.xmlAnt脚本里定义target namepackage-jar jar destfiledist/phonebook.jar basedirout/production/phonebook manifest attribute nameMain-Class valuecom.phonebook.Main/ attribute nameClass-Path valuelib/mysql-connector-java-8.0.33.jar lib/log4j-api-2.20.0.jar lib/log4j-core-2.20.0.jar/ /manifest /jar /target执行ant package-jar后dist/phonebook.jar即生成。双击运行需满足- 本地已安装JRE 8-lib目录与jar同级因Class-Path指向相对路径-db.properties必须在jar同目录否则读取失败。避坑技巧如果双击jar没反应用命令行java -jar phonebook.jar查看报错。常见原因是lib路径不对此时把lib整个文件夹复制到jar所在目录即可。这个细节我在毕设答辩现场帮过12个学生。5. 常见问题与排查技巧实录5.1 数据库连接失败的五大高频场景与速查表现象可能原因快速排查命令解决方案Communications link failureMySQL服务未启动netstat -an \| findstr :3306Windows启动MySQL服务XAMPP控制面板Access denied for user rootlocalhost密码错误或用户权限不足mysql -u root -p重置root密码ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 新密码;Unknown database phonebookphone.sql未执行或执行失败mysql -u root -p -e SHOW DATABASES;重新执行phone.sql注意选择正确的数据库编码utf8mb4No suitable driver foundJDBC驱动jar缺失或版本不匹配ls lib/ \| grep mysql确认lib/mysql-connector-java-8.0.33.jar存在且db.properties里URL用com.mysql.cj.jdbc.DriverThe server time zone value ... is unrecognized时区配置缺失SELECT global.time_zone, session.time_zone;在db.url后追加serverTimezoneAsia/Shanghai5.2 Swing界面卡顿的三大根源与修复方案卡顿是Swing项目最常被诟病的问题根源几乎都出在线程模型上在EDT里执行耗时操作比如点击“加载全部联系人”按钮后直接调用contactDao.findAll()数据库查询阻塞UI线程。修复用SwingWorkerVoid, Void包装doInBackground()里执行DAO操作done()里更新JTable。频繁调用repaint()在paintComponent()里写复杂绘图逻辑或循环调用repaint()。修复重写paintComponent(Graphics g)时先调用super.paintComponent(g)再用Graphics2D做必要绘制避免在定时器里每10ms调用一次repaint()。JTable模型更新不当用DefaultTableModel.addRow()逐条添加1000条数据触发1000次视图刷新。修复先构建VectorVectorObject数据集再调用setDataVector(data, columnNames)一次性刷新。我的独家技巧在MainFrame构造函数末尾加一行SwingUtilities.invokeLater(() - System.out.println(UI ready));可以确认EDT是否正常启动。如果这行不打印说明Swing初始化失败需检查main()方法是否用了SwingUtilities.invokeLater()包裹。5.3 模糊搜索不准的调试路径搜索结果为空或不全按此顺序排查确认数据编码执行SHOW CREATE TABLE contacts;检查name字段字符集是否为utf8mb4。如果不是执行ALTER TABLE contacts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;检查SQL执行计划在MySQL客户端执行EXPLAIN SELECT * FROM contacts WHERE name LIKE %张%;看type是否为ALL全表扫描。如果是说明索引未生效需重建索引验证Java字符串处理在ContactService.searchByName()里打断点检查传入的keyword是否被意外trim()或toLowerCase()。中文搜索必须保持原样LIKE本身不区分大小写测试纯SQL把Java生成的SQL复制到MySQL客户端执行看结果是否符合预期。如果SQL结果正确但Java显示为空问题在ContactTableModel的getValueAt()方法返回了null。5.4 毕设答辩高频问题应答清单基于近三年答辩记录整理出老师最爱问的8个问题及应答要点Q为什么用Swing不用JavaFXASwing是JDK标准GUI库零依赖、学习成本低能更纯粹地训练Java核心能力事件驱动、线程模型、MVC分层。JavaFX虽新但其Scene Builder和CSS样式会分散对Java逻辑的关注。Q密码加密为什么选BCrypt而不是MD5AMD5是快速哈希易被彩虹表破解BCrypt是自适应慢哈希内置盐值和迭代次数能有效抵御暴力破解。BCrypt.hashpw(raw, BCrypt.gensalt(12))中12表示log2(4096)次迭代平衡安全与性能。Q联系人删除是物理删除还是逻辑删除A当前是物理删除DELETE FROM。若需逻辑删除可增加is_deleted TINYINT(1) DEFAULT 0字段所有查询加WHERE is_deleted0条件并在DAO层统一拦截。Q如何保证多用户同时编辑同一条联系人A采用乐观锁机制在Contact实体中增加updated_time字段更新SQL带WHERE id? AND updated_time?条件。若影响行数为0说明已被他人修改提示用户“数据已变更请刷新后重试”。Q系统有没有考虑数据备份A在util/BackupUtil.java里实现了MySQL备份功能调用mysqldump命令生成SQL文件。毕设中可演示“导出联系人CSV”功能这是更实用的备份方式。Q界面布局用的什么管理器为什么不用绝对定位A主界面用BorderLayout表格区域用JScrollPane嵌套JTable输入表单用GridBagLayout。绝对定位null layout会导致窗口缩放时组件错位违背Swing响应式设计原则。Q如果要加“导出Excel”功能怎么实现A引入Apache POI依赖在ContactService.exportToExcel()方法中创建XSSFWorkbook遍历联系人列表写入XSSFSheet最后用response.getOutputStream()输出流返回浏览器。注意内存溢出风险大数据量需用SXSSF。Q项目最大的技术难点是什么A是Swing线程安全与数据库事务的协同。比如“批量导入1000条联系人”既要保证UI进度条实时更新SwingWorker.publish()又要确保数据库事务原子性所有插入成功才提交任一失败回滚。这需要精确控制EDT与后台线程的数据传递。6. 毕设材料使用指南论文、视频、源码的协同价值6.1 论文.docx不只是文字堆砌而是技术决策的说明书这份论文不是模板套用而是每一章都对应开发中的真实决策点-第三章“系统设计”详细画出了Swing事件流图LoginFrame → MainFrame → AddContactDialog的调用链标注了每个Dialog的模态属性setModal(true)和关闭策略DISPOSE_ON_CLOSE-第四章“数据库设计”不仅列了ER图还解释了为什么contacts.user_id不设为NOT NULL——因为初期可能允许游客模式虽未实现但预留扩展-第五章“系统测试”附了JUnit测试覆盖率报告JaCoCo生成重点展示ContactServiceTest对边界条件的覆盖空姓名、超长电话、非法邮箱等12种异常场景。使用建议答辩PPT不必照搬论文全文而是提取“技术亮点页”比如一页放BCrypt密码校验流程图一页放SwingWorker异步加载联系人时序图让老师一眼看到你的深度。6.2 系统演示视频.mp43分钟讲清所有核心功能视频不是功能罗列而是按用户旅程拍摄-0:00-0:30从空白桌面双击phonebook.jar展示启动过程、登录框出现、输入账号密码-0:31-1:15登录后主界面演示“添加联系人”全过程填表单→点保存→列表实时刷新-1:16-2:00双击列表项编辑修改电话后点保存验证updated_time字段变更-2:01-2:45在搜索框输入“张”展示模糊匹配效果右键删除验证级联-2:46-3:00退出系统重启jar验证数据持久化联系人仍在。关键技巧视频里所有操作都用鼠标高亮圈出OBS录制时开启鼠标点击特效避免老师看不清操作位置。结尾定格在“数据持久化验证”画面强化核心价值。6.3 源码与文档的联动学习法不要孤立看源码。推荐按此路径学习1.先看phone.sql理解表结构和约束再看entity/Contact.java字段是否一一对应2.再看dao/ContactDaoImpl.java对照SQL脚本里的建表语句理解PreparedStatement参数顺序3.接着看ui/MainFrame.java找到table.addMouseListener(new ContactTableMouseListener())跳转到ContactTableMouseListener看双击逻辑4.最后看service/ContactService.java理解业务层如何组合DAO调用比如addContact()里先校验邮箱唯一性再调用DAO保存。这种“数据库→实体→DAO→Service→UI”的逆向追踪比从Main.java正向阅读更能建立全局认知。我指导的学生中用此法一周内就能独立修改“增加生日字段”功能。7. 后续扩展建议从毕设到真实项目的跃迁路径这个通讯录不是终点而是你技术成长的跳板。根据学生反馈我梳理出三条务实扩展路径路径一增强实用性适合想快速提升工程能力- 加“联系人头像上传”用JFileChooser选择图片存为BLOB字段JTable单元格重写TableCellRenderer显示缩略图- 加“通话记录”模块新建calls表关联contacts.id记录时间、类型呼入/呼出、时长用JFreeChart画月度通话统计图- 加“数据导出”支持导出为CSV/Excel/PDF用Apache POI和iText实现。路径二提升架构感适合考研或进阶学习- 将Swing替换为JavaFX体验现代GUI的CSS样式、FXML布局、Property绑定- 引入Spring Boot把DAO层改为JPA Repository用Transactional管理事务体会IoC容器威力- 增加REST API层用Postman测试为未来转Web开发铺路。路径三深化安全意识适合想冲击高质量毕设- 实现“登录失败锁定”连续5次失败后users.locked_until字段设为当前时间30分钟登录时校验- 加“操作审计日志”所有增删改操作记录到audit_log表含操作人、IP桌面应用可记InetAddress.getLocalHost().getHostAddress()、时间、详情- 做“敏感信息脱敏”列表中电话显示为138****1234邮箱显示为z***xxx.com在ContactTableModel.getValueAt()里处理。最后分享一个小技巧在src/test/java里写一个StressTest.java用10个线程并发执行1000次添加联系人观察数据库连接池是否撑得住。这种压力测试能让答辩时老师眼前一亮——因为你已经超越了“功能实现”开始思考“系统可靠性”。这个通讯录项目就像一把精心锻造的瑞士军刀它不大但每个刃口都磨得锋利它不炫但每处细节都经得起推敲。当你亲手把它跑起来看着自己输入的名字出现在表格里那一刻的成就感远胜于背十页PPT。代码世界里真正的“精通”从来不是知道多少名词而是亲手解决过多少个“为什么点不动”“为什么搜不到”“为什么存不进”的具体问题。现在就去解压那个压缩包打开IDEA点下那个绿色的Run按钮吧——你的第一个可交付Java桌面应用正在等待你唤醒。本文还有配套的精品资源点击获取简介一款可以直接运行的Java桌面通讯录工具用Swing做界面MySQL存数据。有独立用户系统——支持新用户注册、已有账号登录登录后能改密码、浏览全部联系人。联系人管理功能齐全新增时填姓名电话邮箱地址等信息点击已有条目可修改支持单条删除和按姓名模糊搜索。压缩包里东西很全源码src目录结构清晰、编译好的class文件out目录、所需jar包lib目录、建库建表SQL脚本phone.sql、毕业论文文档论文.docx、系统操作演示视频MP4格式、IntelliJ IDEA项目配置文件.idea和Phone.iml。不需要额外配置导入IDE就能跑适合Java GUI初学者练手也适合作为课程设计或本科毕业设计的参考实现。本文还有配套的精品资源点击获取