JavaSwing项目ATM自动提款机(mysql数据库)+详细报告

本文主要是介绍JavaSwing项目ATM自动提款机(mysql数据库)+详细报告,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

第一章 引言... 1

1.1 设计目的... 1

1.2 相关开发工具介绍... 1

第二章 数据库需求分析... 2

2.1 系统功能分析... 2

2.2 功能模块设计... 2

第三章 数据库概念结构设计... 3

3.1 概念模型... 3

3.2 E-R图... 3

第四章 数据库逻辑结构设计... 4

4.1 关系模型设计... 4

4.2 数据模型的优化... 4

第五章 数据录入调试及运行... 5

第六章 总结... 6

第七章 参考文献... 7

第一章 引言

1.1 设计目的

本系统设计的目的是开发一个功能全面且用户友好的自动取款机(ATM)系统,旨在模拟银行取款机的基本操作,包括取款、存款、查询余额、修改密码、转账、查询记录和导出记录等功能。通过开发该系统,用户能够体验并熟悉ATM机的操作流程,同时为进一步研究和实际应用打下基础。

1.2 相关开发工具介绍

本系统的开发使用了以下工具和技术:

  1. Java编程语言:Java是一种面向对象的编程语言,具有跨平台特性和丰富的类库,适用于开发各种应用程序。
  2. JDBC:Java数据库连接(JDBC)是一种用于执行SQL语句的Java API,可以连接和操作各种数据库。
  3. MySQL数据库:MySQL是一个流行的关系型数据库管理系统,以其可靠性和高性能广泛应用于各种场合。
  4. Swing:Swing是Java的GUI工具包,用于创建图形用户界面(GUI)应用程序。

第二章 数据库需求分析

2.1 系统功能分析

本系统的主要功能包括:

  1. 用户登录和注册
  2. 查询余额
  3. 存款
  4. 取款
  5. 转账
  6. 修改密码
  7. 查询交易记录
  8. 导出交易记录

这些功能需要与数据库交互,以实现用户数据的存储、修改和查询。

2.2 功能模块设计

系统功能模块设计如下:

  1. 用户模块:包括用户的注册、登录、修改密码。
  2. 账户管理模块:包括查询余额、存款、取款、转账。
  3. 交易记录模块:包括查询和导出交易记录。

第三章 数据库概念结构设计

3.1 概念模型

概念模型是对现实世界中实体及其关系的抽象。在本系统中,主要涉及以下实体:

  1. 用户(User)
  2. 账户(Account)
  3. 交易记录(TransactionRecord)
    1. 流程图和E-R图

ATM系统流程图

ATM系统E-R

第四章 数据库逻辑结构设计

    1. 关系模型设计

根据概念模型和E-R图,我们设计了以下关系模型(部分):

表结构:actionrecord

功能:记录用户的操作记录,包括取款、存款和转账等操作。

结构:

DROP TABLE IF EXISTS `actionrecord`;

CREATE TABLE `actionrecord` (

  `time` datetime NULL DEFAULT NULL,

  `cardnumber` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `operation` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `size` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  INDEX `cardnumber`(`cardnumber`) USING BTREE,

  CONSTRAINT `actionrecord_ibfk_1` FOREIGN KEY (`cardnumber`) REFERENCES `alluser` (`cardnumber`) ON DELETE RESTRICT ON UPDATE RESTRICT

) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:admin

·  功能:存储所有用户的信息,包括姓名、性别、电话号码、卡号、密码、余额、身份证号码等。

·  结构

DROP TABLE IF EXISTS `alluser`;

CREATE TABLE `alluser` (

  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `sex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `cardnumber` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,

  `password` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `money` int(11) NULL DEFAULT NULL,

  `idnumber` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,

  PRIMARY KEY (`cardnumber`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:alluser
  • 功能:存储所有用户的信息,包括姓名、性别、电话号码、卡号、密码、余额、身份证号码等。
  • 结构

DROP TABLE IF EXISTS `alluser`;

CREATE TABLE `alluser` (

  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `sex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `cardnumber` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,

  `password` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `money` int(11) NULL DEFAULT NULL,

  `idnumber` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,

  PRIMARY KEY (`cardnumber`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:employees
  • 功能:存储员工的信息,包括员工ID、姓名、薪水和状态等。
  • 结构:

DROP TABLE IF EXISTS `employees`;

CREATE TABLE `employees` (

  `eid` int(11) NOT NULL AUTO_INCREMENT,

  `ename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `salary` float NULL DEFAULT NULL,

  `state` int(11) NULL DEFAULT NULL,

  PRIMARY KEY (`eid`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:goods
  • 功能:存储商品信息,包括商品ID、商品名称、价格、商品点数、种类ID和数量等。
  • 结构

DROP TABLE IF EXISTS `goods`;

CREATE TABLE `goods` (

  `goodsid` int(11) NOT NULL AUTO_INCREMENT,

  `goodsname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `price` float NULL DEFAULT NULL,

  `goodspoint` int(11) NULL DEFAULT NULL,

  `kindid` int(11) NULL DEFAULT NULL,

  `num` int(11) NULL DEFAULT NULL,

  PRIMARY KEY (`goodsid`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:kinds
  • 功能:存储商品种类的信息,包括种类ID和种类名称。
  • 结构

DROP TABLE IF EXISTS `kinds`;

CREATE TABLE `kinds` (

  `kindid` int(11) NOT NULL AUTO_INCREMENT,

  `kindname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  PRIMARY KEY (`kindid`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:transactions
  • 功能:记录用户的交易信息,包括交易ID、用户ID、VIP ID、商品ID、数量、总价和交易时间等。
  • 结构

DROP TABLE IF EXISTS `transactions`;

CREATE TABLE `transactions` (

  `transid` int(11) NOT NULL AUTO_INCREMENT,

  `userid` int(11) NULL DEFAULT NULL,

  `vipid` int(11) NULL DEFAULT NULL,

  `goodsid` int(11) NOT NULL,

  `quantity` int(11) NOT NULL,

  `totalprice` float NOT NULL,

  `transtime` timestamp NULL DEFAULT CURRENT_TIMESTAMP,

  PRIMARY KEY (`transid`) USING BTREE,

  INDEX `userid`(`userid`) USING BTREE,

  INDEX `vipid`(`vipid`) USING BTREE,

  INDEX `goodsid`(`goodsid`) USING BTREE,

  CONSTRAINT `transactions_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `users` (`uid`) ON DELETE RESTRICT ON UPDATE RESTRICT,

  CONSTRAINT `transactions_ibfk_2` FOREIGN KEY (`vipid`) REFERENCES `vip` (`vipid`) ON DELETE RESTRICT ON UPDATE RESTRICT,

  CONSTRAINT `transactions_ibfk_3` FOREIGN KEY (`goodsid`) REFERENCES `goods` (`goodsid`) ON DELETE RESTRICT ON UPDATE RESTRICT

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

表结构:users
  • 功能:存储用户的信息,包括用户ID、用户名、密码和积分等。
  • 结构

DROP TABLE IF EXISTS `users`;

CREATE TABLE `users` (

  `uid` int(11) NOT NULL AUTO_INCREMENT,

  `uname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `upass` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `upoint` int(11) NULL DEFAULT NULL,

  PRIMARY KEY (`uid`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表结构:vip
  • 功能:存储VIP用户的信息,包括VIP ID、VIP用户名、密码和积分等。
  • 结构

DROP TABLE IF EXISTS `vip`;

CREATE TABLE `vip` (

  `vipid` int(11) NOT NULL AUTO_INCREMENT,

  `vipname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `vippass` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

  `vippoint` int(11) NULL DEFAULT NULL,

  PRIMARY KEY (`vipid`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;

表关系图
 
关键代码:

AdministratorUI类主要负责两个界面的初始化和事件处理:

  1. 登录界面:管理员和普通用户可以在此登录。
  2. 管理员界面:管理员可以进行用户的增、删、改、查操作。
public static void init() {
    jframe_1.setSize(260,200);
    jframe_1.setLayout(new FlowLayout());
    jframe_1.setResizable(false);
    jframe_1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    JLabel jlabel = new JLabel("  ATM 模拟系统  ");
    JLabel jlabel_1 = new JLabel("卡  号:");
    JLabel jlabel_2 = new JLabel("密  码:");
 
    jpassword.setEchoChar('*');
    Font font = new Font("宋体",Font.BOLD,26);
    Font font_1 = new Font("宋体",Font.BOLD,16);
    jlabel.setFont(font);
    jlabel_1.setFont(font_1);
    jlabel_2.setFont(font_1);
 
    JButton jbutton_1 = new JButton("管理员登录");
    JButton jbutton_2 = new JButton("用户登录");
    jbutton_1.setFont(font_1);
    jbutton_2.setFont(font_1);
 
    jframe_1.add(jlabel);
    jframe_1.add(jlabel_1);
    jframe_1.add(jtext);
    jframe_1.add(jlabel_2);
    jframe_1.add(jpassword);
    jframe_1.add(jbutton_1);
    jframe_1.add(jbutton_2);
 
    // 注册 管理员登录界面 的监听
    jbutton_1.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            String username = jtext.getText();
            String password = new String(jpassword.getPassword());
            if (MysqlOperation.isAdmin(username, password)) {
                JOptionPane.showMessageDialog(
                        jbutton_1,
                        "登录成功!\n欢迎使用ATM管理员系统!",
                        "提示",
                        JOptionPane.INFORMATION_MESSAGE
                );
                jframe_1.dispose();
                AdministratorUI.init_1();
            } else {
                JOptionPane.showMessageDialog(
                        jbutton_1,
                        "用户名或密码错误!\n请重新输入!",
                        "警告",
                        JOptionPane.WARNING_MESSAGE
                );
            }
        }
    });
 
    jbutton_2.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            String password = new String(jpassword.getPassword());
            if (MysqlOperation.selectUserText(jtext.getText())) {
                if (password.equals(MysqlOperation.selectPasswordText(jbutton_2))) {
                    JOptionPane.showMessageDialog(
                            jbutton_2,
                            "登录成功!\n欢迎使用ATM模拟程序!",
                            "提示",
                            JOptionPane.INFORMATION_MESSAGE
                    );
                    jframe_1.dispose();
                    UserUI.init();
                } else {
                    JOptionPane.showMessageDialog(
                            null,
                            "密码错误!\n请重新输入!",
                            "警告",
                            JOptionPane.WARNING_MESSAGE
                    );
                }
            } else {
                JOptionPane.showMessageDialog(
                        null,
                        "不存在当前用户!\n请联系管理员注册!",
                        "警告",
                        JOptionPane.WARNING_MESSAGE
                );
            }
        }
    });
 
    jframe_1.setLocationRelativeTo(null);
    jframe_1.setVisible(true);
}
 
添加用户界面:
public static void init_2() {
    jpanel_1.removeAll();
    jpanel_1.updateUI();
 
    String userInformation[] = {"姓 名:", "性 别:", "电 话:", "身份证号:", "密 码:", "余额:"};
    JLabel jlabel[] = new JLabel[userInformation.length];
    JTextField jtextfield[] = new JTextField[userInformation.length];
 
    for (int i = 0; i < userInformation.length; i++) {
        jlabel[i] = new JLabel(userInformation[i]);
        jpanel_1.add(jlabel[i]);
        jtextfield[i] = new JTextField(12);
        jpanel_1.add(jtextfield[i]);
    }
 
    JButton jbutton_1 = new JButton("提交");
    JButton jbutton_2 = new JButton("清除");
    jpanel_1.add(jbutton_1);
    jpanel_1.add(jbutton_2);
 
    jbutton_1.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            String idNumber = jtextfield[3].getText();
            if (idNumber.length() != 18) {
                JOptionPane.showMessageDialog(jbutton_1, "身份证号需18位!", "警告", JOptionPane.WARNING_MESSAGE);
                return;
            }
            MysqlOperation.addUser(jbutton_1, jtextfield);
        }
    });
 
    jbutton_2.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < jtextfield.length; i++) {
                jtextfield[i].setText("");
            }
        }
    });
}
 
MysqlOperation 
功能:负责管理与 MySQL 数据库的交互,包括用户信息的添加、修改、删除、查询等操作。
 
添加用户
public static void addUser(JButton jbutton_1, JTextField jtextfield[]) {
    Connection con = null;
    Statement stat = null;
    String sql = null;
    try {
        con = MysqlOperation.getConnection();
        con.setAutoCommit(false);
        stat = con.createStatement();
        // 生成随机的18位银行卡号
        String cardnumber = generateCardNumber();
        sql = "INSERT INTO alluser (name, sex, phone, idnumber, cardnumber, password, money) VALUES ('" +
                jtextfield[0].getText() + "','" + jtextfield[1].getText() + "','" +
                jtextfield[2].getText() + "','" + jtextfield[3].getText() + "','" +
                cardnumber + "','" + jtextfield[4].getText() + "'," + Integer.parseInt(jtextfield[5].getText()) + ")";
        stat.executeUpdate(sql);
        con.commit();
        JOptionPane.showMessageDialog(jbutton_1, "添加用户信息成功!\n银行卡号:" + cardnumber, "提示", JOptionPane.INFORMATION_MESSAGE);
    } catch (SQLException e) {
        try {
            if (con != null) con.rollback();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        JOptionPane.showMessageDialog(jbutton_1, "添加用户信息失败!", "警告", JOptionPane.WARNING_MESSAGE);
    } finally {
        try {
            if (stat != null) stat.close();
            if (con != null) con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
 
UserUI 
功能:负责用户主界面的实现与用户交互功能的实现。它使用 Swing 库创建图形用户界面,并调用 MysqlOperation 类中的方法与数据库进行交互,执行存款、取款、查询、转账等操作。
类结构:

package atmsystem;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;

public class UserUI {
   
// 定义窗口
   
public static JFrame jframe_3 = new JFrame();
   
// 定义文本区用于显示信息
   
public static JTextArea jtextArea_1 = new JTextArea();

   
// 用户主界面
   
public static void init() {
      
// 设置窗口名
      
jframe_3.setTitle("用户界面+卡号:" + AdministratorUI.jtext.getText());
      
// 窗口大小
      
jframe_3.setSize(400, 400);
      
// 空布局
      
jframe_3.setLayout(null);
      
// 窗口不可调整
      
jframe_3.setResizable(false);
      
// 关闭窗口则退出程序
      
jframe_3.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      
// 设置文本区不能编辑
      
jtextArea_1.setEditable(false);
      
jtextArea_1.setLineWrap(true); // 激活自动换行功能
      
jtextArea_1.setWrapStyleWord(true); // 激活断行不断字功能
      
// jtextArea_1作为可滚动面板sp的显示区域
      
JScrollPane sp = new JScrollPane(jtextArea_1);
      
sp.setBounds(100, 80, 200, 200);
      
jframe_3.add(sp);

      
// 按钮名
      
String jbuttonName[] = {"取款", "存款", "查询", "安全退出", "修改密码", "转账", "查询记录", "导出记录"};
      
// 定义按钮
      
JButton jbutton[] = new JButton[jbuttonName.length];
      
// 实例化
      
for (int i = 0; i < jbuttonName.length; i++) {
         
jbutton[i] = new JButton(jbuttonName[i]);
       }
      
// 设置按钮的大小和位置
      
jbutton[0].setBounds(0, 60, 100, 40);
      
jbutton[1].setBounds(0, 120, 100, 40);
      
jbutton[2].setBounds(0, 190, 100, 40);
      
jbutton[3].setBounds(0, 260, 100, 40);
      
jbutton[4].setBounds(300, 60, 100, 40);
      
jbutton[5].setBounds(300, 120, 100, 40);
      
jbutton[6].setBounds(300, 190, 100, 40);
      
jbutton[7].setBounds(300, 260, 100, 40);
      
// 将按钮添加到窗口
      
jframe_3.add(jbutton[0]);
      
jframe_3.add(jbutton[1]);
      
jframe_3.add(jbutton[2]);
      
jframe_3.add(jbutton[3]);
      
jframe_3.add(jbutton[4]);
      
jframe_3.add(jbutton[5]);
      
jframe_3.add(jbutton[6]);
      
jframe_3.add(jbutton[7]);

      
// 注册所有按钮的监听
      
// 取款按钮
      
jbutton[0].addActionListener(new ActionListener() {
         
@Override
         
public void actionPerformed(ActionEvent e) {
            
int money_1 = 0; // 取款金额
            
int money_2 = 0; // 余额
            
String str = null;
            
// 弹出提示界面
            
str = JOptionPane.showInputDialog(null, "请输入取款金额:",
                  
"提示", JOptionPane.QUESTION_MESSAGE); // 输入对话框
            
// 如果str为空则说明用户取消取款,结束此方法
            
if (str == null) {
               
return;
             }
            
money_1 = Integer.parseInt(str);
            
money_2 = MysqlOperation.selectMoney(AdministratorUI.jtext.getText());
            
// 判断金额是否规范
            
if (money_1 % 100 == 0 && money_1 <= 5000) {
               
// 判断余额是否足够
               
if (money_1 < money_2) {
                  
money_2 = money_2 - money_1;
                  
// 取款,调用数据库方法
                  
MysqlOperation.withdraw(money_1, money_2);
                  
// 向文本区添加信息
                  
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                         +
取款" + money_1 + "\n");
                  
// 提示
                  
JOptionPane.showMessageDialog(
                        
null,
                        
"取款" + money_1 + "元成功!",
                        
"提示",
                        
JOptionPane.INFORMATION_MESSAGE
                  
);
                }
else {
                  
// 提示余额不足
                  
JOptionPane.showMessageDialog(
                        
null,
                        
"您的余额不足!",
                        
"警告",
                        
JOptionPane.WARNING_MESSAGE
                  
);
                }
             }
else {
               
// 提示
               
JOptionPane.showMessageDialog(
                     
null,
                     
"取款金额要为100的倍数且总额不超过5000元!",
                     
"警告",
                     
JOptionPane.WARNING_MESSAGE
               
);
             }
          }
       });
       
// 存款按钮
      
jbutton[1].addActionListener(new ActionListener() {

         
@Override
         
public void actionPerformed(ActionEvent e) {
            
int money_1 = 0; // 存款金额
            
int money_2 = 0; // 余额
            
String str = null;
            
// 弹出提示界面
            
str = JOptionPane.showInputDialog(null, "请输入存款金额:",
                  
"提示", JOptionPane.QUESTION_MESSAGE); // 输入对话框
            
// 如果str为空则说明用户取消存款,结束此方法
            
if (str == null) {
               
return;
             }
            
money_1 = Integer.parseInt(str);
            
money_2 = MysqlOperation.selectMoney(AdministratorUI.jtext.getText());
            
// 判断金额是否规范
            
if (money_1 > 0 && money_1 % 100 == 0) {
               
money_2 = money_2 + money_1;
               
// 存款,调用数据库方法
               
MysqlOperation.deposit(money_1, money_2);
               
// 向文本区添加信息
               
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                      +
存款" + money_1 + "\n");
               
// 提示
               
JOptionPane.showMessageDialog(
                     
null,
                     
"存款" + money_1 + "元成功!",
                     
"提示",
                     
JOptionPane.INFORMATION_MESSAGE
               
);
             }
else {
               
// 提示
               
JOptionPane.showMessageDialog(
                     
null,
                     
"金额必须大于0且为100的整数倍!",
                     
"警告",
                     
JOptionPane.WARNING_MESSAGE
                
);
             }
          }
       });
      
// 查询按钮
      
jbutton[2].addActionListener(new ActionListener() {

         
@Override
         
public void actionPerformed(ActionEvent e) {
            
// 提示
            
JOptionPane.showMessageDialog(
                  
null,
                  
"当前余额为:" + MysqlOperation.selectMoney(AdministratorUI.jtext.getText()) + "元!",
                  
"提示",
                  
JOptionPane.INFORMATION_MESSAGE
            
);
          }
       });
      
// 安全退出按钮
      
jbutton[3].addActionListener(new ActionListener() {

         
@Override
         
public void actionPerformed(ActionEvent e) {
            
// 提示
            
JOptionPane.showMessageDialog(
                  
null,
                  
"感谢您的使用!\n再见!",
                  
"提示",
                  
JOptionPane.INFORMATION_MESSAGE
            
);
            
// 退出程序
            
System.exit(0);
          }
       });
      
// 修改密码按钮
      
jbutton[4].addActionListener(new ActionListener() {

          
@Override
         
public void actionPerformed(ActionEvent e) {
            
String password_1 = null;
            
String password_2 = null;
            
int i = 1;
            
// 提示注意当前环境
            
JOptionPane.showMessageDialog(
                  
null,
                  
"请确保当前环境安全再修改密码!",
                  
"警告",
                  
JOptionPane.WARNING_MESSAGE
            
);
            
// 提示输入新的密码
            
password_1 = JOptionPane.showInputDialog(null, "请输入新密码:",
                  
"提示", JOptionPane.QUESTION_MESSAGE); // 输入对话框
            
// 如果用户取消则结束方法
            
if (password_1 == null) {
               
return;
             }
            
// 检查
            
// 检查密码是否规范
            
char first = password_1.charAt(0);
            
if (password_1.length() >= 6) {
               
for (i = 1; i < password_1.length(); i++) {
                  
if (password_1.charAt(i) != first) {
                     
// 密码规范,则提示确认密码
                     
password_2 = JOptionPane.showInputDialog(null, "请确认密码:",
                           
"提示", JOptionPane.QUESTION_MESSAGE); // 输入对话框
                     
// 如果用户取消则结束方法
                     
if (password_2 == null) {
                        
return;
                      }
                     
break;
                   }
                }
               
// 如果密码的所有位完全相同,提示密码不规范
               
if (i == password_1.length()) {
                  
JOptionPane.showMessageDialog(
                        
null,
                        
"密码不能每一位都相同!\n修改密码失败!",
                         
"提示",
                        
JOptionPane.WARNING_MESSAGE
                  
);
                  
// 向文本区添加信息
                  
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                         +
" 修改密码失败!\n");
                  
// 结束程序
                  
return;
                }

             }
else {
               
// 提示密码不足6
               
JOptionPane.showMessageDialog(
                     
null,
                     
"密码不足6位!\n修改失败!",
                     
"警告",
                     
JOptionPane.WARNING_MESSAGE
               
);
               
// 向文本区添加信息
               
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                      +
" 修改密码失败!\n");
               
// 结束方法
               
return;
             }
            
// 判断两次密码的输入是否一致
            
if (password_1.equals(password_2)) {
               
// 调用数据库方法修改密码
               
MysqlOperation.changePassword(password_2);
               
// 提示修改密码成功
               
JOptionPane.showMessageDialog(
                     
null,
                     
"修改密码成功!",
                     
"提示",
                     
JOptionPane.INFORMATION_MESSAGE
               
);
               
// 向文本区添加信息
               
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                      +
" 修改密码成功!\n");
             }
else {
               
JOptionPane.showMessageDialog(
                      
null,
                     
"两次密码不一致!\n修改密码失败!",
                     
"提示",
                     
JOptionPane.WARNING_MESSAGE
               
);
             }
          }
       });
      
// 转账按钮
      
jbutton[5].addActionListener(new ActionListener() {

         
@Override
         
public void actionPerformed(ActionEvent e) {
            
String cardnumber = null; // 存储目标卡号
            
int money_1 = 0; // 存储转账金额
            
int money_2 = MysqlOperation.selectMoney(AdministratorUI.jtext.getText()); // 存储当前账户余额
            
// 提示输入目标卡号
            
cardnumber = JOptionPane.showInputDialog(null, "请输入目标卡号:",
                  
"提示", JOptionPane.QUESTION_MESSAGE); // 输入对话框
            
// 如果用户取消则结束方法
            
if (cardnumber == null) {
               
return;
             }
            
// 判断账户是否为自己
            
if (cardnumber.equals(AdministratorUI.jtext.getText())) {
               
// 提示不能向自己转账
               
JOptionPane.showMessageDialog(
                     
null,
                     
"不能向自己转账!\n转账失败!",
                     
"提示",
                     
JOptionPane.WARNING_MESSAGE
               
);
               
// 结束函数
               
return;
             }
            
// 检查当前账户是否存在,不能向自己转账
            
if (MysqlOperation.selectUserText(cardnumber)) {
               
// 存在当前账户,则提示输入转账金额
               
String str = JOptionPane.showInputDialog(null, "请输入转账金额:",
                     
"提示", JOptionPane.QUESTION_MESSAGE); // 输入对话框
               
// 如果用户取消则结束方法
               
if (str == null) {
                  
return;
                }
               
money_1 = Integer.parseInt(str);
               
// 检查当前账户余额是否足够
               
if (money_1 > MysqlOperation.selectMoney(AdministratorUI.jtext.getText())) {
                  
// 提示余额不足
                  
JOptionPane.showMessageDialog(
                        
null,
                        
"余额不足!\n转账失败!",
                        
"提示",
                        
JOptionPane.WARNING_MESSAGE
                  
);
                  
// 向文本区添加信息
                   
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                         +
转账" + money_1 + "元失败!\n");
                  
// 结束方法
                  
return;
                }
else if (money_1 % 100 == 0 && money_1 <= 5000) {
                  
// 调用数据库方法,向目标账户转账
                  
money_2 = money_2 - money_1;
                  
MysqlOperation.transfer(cardnumber, money_1, money_2);
                  
// 提示转账成功
                  
JOptionPane.showMessageDialog(
                        
null,
                        
"转账成功!",
                        
"提示",
                        
JOptionPane.INFORMATION_MESSAGE
                  
);
                  
// 向文本区添加信息
                  
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                         +
转账" + money_1 + "元成功!\n");
                }
else {
                  
// 提示转账金额要为100的倍数且不能大于5000
                  
JOptionPane.showMessageDialog(
                        
null,
                        
"转账金额要为100的倍数且不能大于5000\n转账失败!",
                        
"提示",
                        
JOptionPane.WARNING_MESSAGE
                  
);
                  
// 向文本区添加信息
                  
UserUI.jtextArea_1.append("交易记录:" + UserUI.time() + 卡号:" + AdministratorUI.jtext.getText()
                         +
转账" + money_1 + "元失败!\n");
                }
             }
else {
               
// 提示不存在当前用户
               
JOptionPane.showMessageDialog(
                     
null,
                     
"未查询到当前用户信息!\n转账失败!",
                     
"警告",
                     
JOptionPane.WARNING_MESSAGE
               
);
             }
          }
       });
      
// 查询记录
      
jbutton[6].addActionListener(new ActionListener() {
         
@Override
         
public void actionPerformed(ActionEvent e) {
            
UserUI.showNowUser();
          }
       });

      
// 导出记录
      
jbutton[7].addActionListener(new ActionListener() {
         
@Override
          
public void actionPerformed(ActionEvent e) {
            
MysqlOperation.saveUser();
          }
       });

      
// 窗口居中
      
jframe_3.setLocationRelativeTo(null);
      
// 窗口显示
      
jframe_3.setVisible(true);
    }

   
// 获得时间
   
public static String time() {
      
LocalDateTime dateTime = LocalDateTime.now();
      
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
      
return dateTime.format(formatter);
    }

   
// 查询信息界面
   
public static void showNowUser() {
      
JFrame jf = new JFrame("全部信息");
      
// 关闭则隐藏并释放当前窗口
      
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      
// 创建内容面板
      
JPanel panel = new JPanel();

      
// 表头(列名)
      
String columnNames[] = {"卡号", "姓名", "性别", "电话", "余额", "时间", "操作", "数量"};

      
// 表格所有行数据
      
// 调用数据库方法显示全部信息
      
String rowData[][] = MysqlOperation.showNowUser(jtextArea_1);

      
// 创建一个表格,指定 表头 和 所有行数据
      
JTable table = new JTable(rowData, columnNames);

      
// 设置表格内容颜色
      
table.setForeground(Color.BLACK); // 字体颜色
      
table.setFont(new Font(null, Font.PLAIN, 14)); // 字体样式
      
table.setSelectionForeground(Color.DARK_GRAY); // 选中后字体颜色
      
table.setSelectionBackground(Color.LIGHT_GRAY); // 选中后字体背景
      
table.setGridColor(Color.GRAY); // 网格颜色

      
// 设置表头
      
table.getTableHeader().setFont(new Font(null, Font.BOLD, 14)); // 设置表头名称字体样式
      
table.getTableHeader().setForeground(Color.RED); // 设置表头名称字体颜色
      
table.getTableHeader().setResizingAllowed(false); // 设置不允许手动改变列宽
      
table.getTableHeader().setReorderingAllowed(false); // 设置不允许拖动重新排序各列

      
// 设置行高
      
table.setRowHeight(30);

      
// 第一列列宽设置为130
      
table.getColumnModel().getColumn(0).setPreferredWidth(130);
      
table.getColumnModel().getColumn(1).setPreferredWidth(50);
      
table.getColumnModel().getColumn(2).setPreferredWidth(20);
      
table.getColumnModel().getColumn(3).setPreferredWidth(80);
      
table.getColumnModel().getColumn(4).setPreferredWidth(80);
      
table.getColumnModel().getColumn(5).setPreferredWidth(160);
      
table.getColumnModel().getColumn(6).setPreferredWidth(220);
      
table.getColumnModel().getColumn(7).setPreferredWidth(80);

      
// 设置滚动面板视口大小(超过该大小的行数据,需要拖动滚动条才能看到)
      
table.setPreferredScrollableViewportSize(new Dimension(1000, 500));

      
// 把 表格 放到 滚动面板 中(表头将自动添加到滚动面板顶部)
      
JScrollPane scrollPane = new JScrollPane(table);

      
// 添加 滚动面板 到 内容面板
      
panel.add(scrollPane);

      
// 设置 内容面板 到 窗口
      
jf.setContentPane(panel);

       
jf.pack();
      
jf.setLocationRelativeTo(null);
      
jf.setVisible(true);
    }
}

 
    1. 数据模型的优化

在设计过程中,我们进行了以下优化:

  • 索引:在userIDaccountID上建立索引,以提高查询速度。
  • 数据完整性:使用外键约束保证数据的一致性和完整性。
  • 规范化:确保表结构符合第三范式,避免数据冗余。

第五章 数据录入调试及运行

以下是系统的主要界面及其功能截图:

用户主界面提供了取款、存款、查询余额、修改密码、转账、查询记录和导出记录的功能。用户可以在该界面进行各种操作,所有操作结果会显示在文本区域内。

在取款界面,用户输入取款金额并提交。如果取款金额符合要求且账户余额充足,系统会更新余额并记录交易。

在存款界面,用户输入存款金额并提交。存款成功后,系统会更新余额并记录交易。

点击查询按钮后,系统会显示用户当前的账户余额。

用户可以在此界面修改密码。新密码需要符合一定规范,且两次输入一致。

在转账界面,用户输入目标账户和转账金额并提交。系统会检查账户和余额,并在条件符合时完成转账。

用户可以在此界面查询所有交易记录。记录以表格形式显示,包括卡号、姓名、性别、电话、余额、时间、操作和数量。

用户可以点击导出记录按钮,将交易记录保存到本地文件。

第六章 总结

本次实验开发了一个功能完善的ATM系统,涵盖了用户登录、账户管理、交易记录等模块。通过本次实验,我们掌握了Java GUI编程、数据库设计与操作、系统集成调试等技能。同时,深入理解了银行ATM系统的操作流程和功能实现。

在开发过程中,我们遇到了一些问题,如GUI布局调整、数据库连接异常等,但通过查阅资料和调试,最终解决了这些问题。未来,我们可以进一步优化系统性能,增加更多安全措施和用户体验优化。

第七章 参考文献

  1. Java编程思想(第四版),Bruce Eckel,机械工业出版社,2010年。
  2. 数据库系统概念(第六版),Abraham Silberschatz,McGraw-Hill Education,2010年。
  3. Java核心技术卷I:基础知识(第十版),Cay S. Horstmann,机械工业出版社,2015年。
  4. Swing教程,https://docs.oracle.com/javase/tutorial/uiswing/
  5. MySQL参考手册,MySQL :: MySQL Documentation

vx:miniqq207 

这篇关于JavaSwing项目ATM自动提款机(mysql数据库)+详细报告的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134881

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template