用java GUI 界面和 JDBC 数据库实现ATM机系统
主要类
1、ATM类:
- 用来获取信息和传送信息,进行简单判断,在程序结束释放Data类的资源
- 窗口类使用ATM类
- 从Data类获取信息传给窗口类
- 从窗口获取的信息传给Data类
2、Data类:
- Data类是是用来操作数据库的,改查操作
- 验证、返回、保存信息
3、窗口类
- 窗口类进行界面展示
- 使用ATM类把获取的信息传给Data类
- 从ATM类获取信息,简单判断,展示界面
4、JDBC_Util类
- JDBC工具类
类
类的名字及里面的方法名都是我之前随便取的,没有改。
配置环境
1、jdk1.8;安装mysql
2、新建一个libs文件夹并导入mysql驱动的jar包,创建一个jdbc.properties配置文件
// jdbc.properties配置文件
// atm1是用的数据库名字,注意Data类里数据库语句中表名字
url=jdbc:mysql://localhost:3306/atm1
user=你的mysql的用户名
password=你的mysql用户密码
driver=com.mysql.jdbc.Driver
源代码
java代码
package Bank;
/**
* 用来获取信息和传送信息,进行简单判断,在程序结束释放Data类的资源
* 窗口类使用ATM类
* 从Data类获取信息传给窗口类
* 从窗口获取的信息传给Data类
*/
public class ATM {
//有一个类操作数据的类
private Data data = new Data();
//ATM机里的数据
private double userMoney;//用户账户里的钱
//登录方法
public boolean login(String inUserName,String inUserPassword){
boolean b= false;
if(data.isTrue(inUserName,inUserPassword)){
b = true;
userMoney = data.getMoney();
}
return b;
}
//获取账户余额
public Double getMoney1(){
userMoney = data.getMoney();
return userMoney;
}
//存钱
public boolean saveMoney(Double money){
boolean b = false;
if(money % 100 == 0) { //如果存的钱正确
b = data.changeMoney(money, true);//存上
}
return b;
}
//取钱
public boolean quMoney(Double money){
boolean b = false;
if(money % 100 == 0 && money <= userMoney){
b = data.changeMoney(money, false);
}
return b;
}
//只判断用户账户是否存在
public boolean anotherUser(String inUserName){
//如果该账户存在
boolean b = data.isUser(inUserName);
return b;
}
//进行转账
public void giveMoney(Double money){
data.giveMoney(money);
}
//修改密码实现
public boolean changePassword(String newPassword){
return data.changePassword(newPassword);
}
// 程序结束
public void over(){
// 释放Data类的资源
data.close();
}
}
package Bank;
import JDBC_Utils.JDBC_Util;
import java.sql.*;
/**
* Data类是是用来操作数据库的,改查操作
* 验证、返回、保存信息
*/
public class Data {
private double umoney;//用户余额
private String uname; //用户
private String gname; //被转账用户
private Connection coon = null;// 一般操作连接对象,程序结束时释放
private Connection coon1 = null;// 转账连接对象,程序结束时释放
private PreparedStatement pstmt = null; // 一般操作
private PreparedStatement pstmt1 = null; // 转账时使用
private ResultSet res = null;
private String sql;//sql语句
private String sql1;//sql语句,转账时使用
{
try {
// 获取连接对象
coon = JDBC_Util.getConnection();
coon1 = JDBC_Util.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 获取该账户的余额
* @return 余额
*/
public double getMoney(){
try {
sql = "select * from atm1 where uname= ?";//查询语句
pstmt = coon.prepareStatement(sql);
pstmt.setString(1, uname);
res = pstmt.executeQuery();
if(res.next()){
umoney = res.getDouble("money");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBC_Util.close(res, pstmt, null);//释放资源
}
return umoney;
}
/**
* 判断登录是否成功
*/
public boolean isTrue(String user,String password){
if(user == null || password == null){
return false;
}
try {
sql = "select * from atm1 where uname = ? and password = ?";
pstmt = coon.prepareStatement(sql);
pstmt.setString(1,user);
pstmt.setString(2,password);
res = pstmt.executeQuery();
uname = user;
return res.next();
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBC_Util.close(res, pstmt, null);
}
return false;
}
/**
* 取钱、存钱操作
* @param money 钱数
* @param isOrNot 存钱or取钱
*/
public boolean changeMoney(double money,boolean isOrNot){
if(isOrNot){
sql = "update atm1 set money = money + ? where uname = ?";
}else{
sql = "update atm1 set money = money - ? where uname = ?";
}
return runSql(money,null);
}
/**
* 修改密码
* @param newPassword 新密码
* @return
*/
public boolean changePassword(String newPassword){
if(newPassword == null){
return false;
}
sql = "update atm1 set password = ? where uname = ?";
return runSql(0,newPassword);
}
//执行sql修改操作
private boolean runSql(double money,String newPassword){
try {
if(sql == null){
return false;
}
pstmt = coon.prepareStatement(sql);
if(newPassword == null){
pstmt.setDouble(1, money);
}else{
pstmt.setString(1, newPassword);
}
pstmt.setString(2,uname);
int count = pstmt.executeUpdate();
if(count != 0){
return true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
sql = null;
JDBC_Util.close(res, pstmt, null);
}
return false;
}
/**
* 判断被转帐用户是否存在
* @param user 被转账用户名
* @return
*/
public boolean isUser(String user){
if(user == null){
return false;
}
try {
sql = "select * from atm1 where uname = ?";
pstmt = coon.prepareStatement(sql);
pstmt.setString(1,user);
res = pstmt.executeQuery();
gname = user;
return res.next();
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBC_Util.close(res, pstmt, null);
}
return false;
}
/**
* 转账操作,事务
* @param money 转账数
* @return
*/
public boolean giveMoney(double money){
try {
coon1.setAutoCommit(false); //开启事务
sql = "update atm1 set money = money - ? where uname = ?";
sql1 = "update atm1 set money = money + ? where uname = ?";
pstmt = coon.prepareStatement(sql);
pstmt1 = coon.prepareStatement(sql1);
pstmt.setDouble(1,money);
pstmt.setString(2,uname);
pstmt1.setDouble(1,money);
pstmt1.setString(2,gname);
int a = pstmt.executeUpdate();
int b = pstmt1.executeUpdate();
coon1.commit();//提交事务
if(a !=0 && b!=0) {
return true;
}
} catch (Exception e) {
try {
if(coon1 !=null)
coon1.rollback();//回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally{
JDBC_Util.close(res, pstmt, null);
JDBC_Util.close(null, pstmt1, null);
}
return false;
}
/**
* 释放所有的资源
*/
public void close(){
JDBC_Util.close(res, pstmt, coon);
JDBC_Util.close(res, pstmt1, coon1);
}
}
package JDBC_Utils;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
/**
* JDBC工具类
*/
public class JDBC_Util {
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 从配置文件读取所需要的数据
*/
static{
try {
//创建Properties集合类
Properties pro = new Properties();
//获取src下文件路径---->ClassLoader 类加载器(文件路径不有为中文)
ClassLoader classLoader = new ClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
//加载文件
//pro.load(new FileReader("/D:/java-idea2018File/jdbc/out/production/atm-gui-jdbc/jdbc.properties"));
pro.load(new FileReader(path));
//获取数据赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return 连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/**
* 释放资源
* @param stmt
* @param coon
*/
public static void close(Statement stmt, Connection coon){
close(null,stmt,coon);
}
public static void close(ResultSet res,Statement stmt,Connection coon){
if(res != null){
try{
res.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if (stmt != null) {
try{
stmt.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if (coon != null) {
try{
coon.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
package MyJFrame;
import Bank.ATM;
import javax.swing.*;
import java.awt.*;
/**
* 窗口类进行界面展示
* 使用ATM类把获取的信息传给Data类
* 从ATM类获取信息,简单判断,展示界面
* 自己创造的界面的父类
*/
public class MyJFrame extends JFrame {
//设置字体供子类使用
public static final Font FONT_SIZE_10 = new Font("宋体",Font.PLAIN,18);
public static final Font FONT_SIZE_20 = new Font("宋体",Font.PLAIN,20);
public static final Font FONT_SIZE_25 = new Font("宋体",Font.PLAIN,25);
//给一个静态公共不可改变的ATM对象作为属性,供子类使用
public static final ATM atm = new ATM();
//创建窗体
public MyJFrame(String title){
super(title);
//设置窗体不可改变
setResizable(false);
//设置窗体大小
setSize(600,600);
//设置窗体居中
setLocationRelativeTo(null);
}
//无参构造,创建无标题窗体
public MyJFrame(){
this("");
}
//设置弹窗方法供子类使用(传入字符串并显示出)
protected void showMessageDialog(String str){
JOptionPane.showMessageDialog(this,str);
}
}
package MyJFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 登录界面
* 继承MyJFrame
*/
public class LoginJFrame extends MyJFrame {
public LoginJFrame(){
super("欢迎使用ATM机");
//设置窗体可关闭
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置组件
init();
//界面可视化
setVisible(true);
}
//初始化界面
private void init(){
//创建面板对象,并定义为空布局
JPanel jp = new JPanel(null);
//添加标签
JLabel jl1 = new JLabel("账号:");
JLabel jl2 = new JLabel("密码:");
//设置标签字体
jl1.setFont(FONT_SIZE_20);
jl2.setFont(FONT_SIZE_20);
//设置标签在面板中的位置
jl1.setBounds(100,100,70,70);
jl2.setBounds(100,250,70,70);
//添加文本框
JTextField jtf = new JTextField(20);
//添加密码文本框
JPasswordField jpf = new JPasswordField(20);
//设置文本框位置
jtf.setBounds(200,115,200,40);
jpf.setBounds(200,265,200,40);
//添加按钮
JButton jb = new JButton("登录");
//设置按钮文字大小
jb.setFont(FONT_SIZE_20);
//设置按钮位置及大小
jb.setBounds(250,400,100,50);
//设置面板背景颜色
jp.setBackground(Color.YELLOW);
//内部类进行事件处理
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入的账号和密码
String userName = jtf.getText();
String userPassword = new String(jpf.getPassword());
//验证是否正确
boolean aBoolean = atm.login(userName,userPassword);
if(aBoolean){
//登录成功
dispose();//关闭登录界面
//打开功能界面
new WorkingJFrame();
}
else
showMessageDialog("账号或密码错误");//调用父类弹窗方法
}
});
//添加组件
jp.add(jl1);
jp.add(jtf);
jp.add(jl2);
jp.add(jpf);
jp.add(jb);
//窗体添加面板
add(jp);
}
public static void main(String[] args) {
new LoginJFrame();//先创建登录界面
}
}
package MyJFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 功能界面
* extends MyJFrame
*/
public class WorkingJFrame extends MyJFrame {
public WorkingJFrame(){
super("功能界面");
init();
setVisible(true);
}
//初始化功能界面
private void init(){
//设置第一个面板对象
JPanel jp1 = new JPanel();
//创建标签,将标签添加到第一个面板上
JLabel jb = new JLabel("请选择要进行的操作:");
jb.setFont(FONT_SIZE_25);//设置标签字体大小
jp1.add(jb);
jp1.setBackground(Color.CYAN);
//将第一个面板添加到窗体上方(JFrame窗体是边界布局)
add(jp1, BorderLayout.NORTH);
//创建第二个面板对象(空布局,自己设置按钮位置及大小),然后将按钮添加
JPanel jp2 = new JPanel(null);
//字符串数组存储各个按钮名字,然后循环设置按钮名字
String[] str = {"1、余额查询","2、取钱","3、存钱","4、转账","5、修改密码","6、退出系统"};
//int二维数组储存各个按钮位置及大小信息,循环设置
int[][] xy = new int[][]{{50,100,200,50},{350,100,200,50},{50,200,200,50},{350,200,200,50},{50,300,200,50},{350,300,200,50}};
for(int i = 0;i < str.length;i ++){
JButton jButton = new JButton(str[i]);//创建按钮
jButton.setFont(FONT_SIZE_20);//设置按钮字体大小
jButton.setBounds(xy[i][0],xy[i][1],xy[i][2],xy[i][3]);//设置按钮位置及大小
jButton.addActionListener(listener);//按钮注册监听器
jp2.add(jButton);//将按钮添加
}
//设置jp2背景颜色
jp2.setBackground(Color.GRAY);
//将第二个面板添加到窗体(JFrame窗体中间)
add(jp2);
}
//创建事件监听器
private ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();//获取按钮上的字
//switch选择功能,且每次功能结束回到该界面,关闭已操作完的功能界面
switch(actionCommand){
case "1、余额查询":
getMoney();
break;
case "2、取钱":
quMoney();
break;
case "3、存钱":
cunMoney();
break;
case "4、转账":
giveMoney();
break;
case "5、修改密码":
changePassword();
break;
case "6、退出系统":
over();
break;
}
}
};
//查询余额功能
private void getMoney(){
showMessageDialog("您的账户余额为:" + atm.getMoney1());//调用父类方法弹窗
}
//取钱功能
private void quMoney(){
new QuMoneyJFrame();//创建取钱界面
dispose();//关闭该界面
}
//存钱功能
private void cunMoney(){
new CunMoneyJFrame();
dispose();
}
//转账功能
private void giveMoney(){
new GiveMoneyJFrame();
dispose();
}
//修改密码功能
private void changePassword(){
new ChangePasswordJFrame();
dispose();
}
//退出系统功能
private void over(){
atm.over();//调用方法操作文件
dispose();
}
}
package MyJFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 中间窗口,存钱、取钱、转账、修改密码界面的父类
* 组装存钱、取钱、转账、修改密码界面
*/
public class CentreJFrame extends MyJFrame {
//空布局面板,自己设置组件位置及大小
protected JPanel jp = new JPanel(null);
//输入金额标签
protected JLabel jl = new JLabel("请输入金额:");
//输入金额文件框
protected JTextField jtf = new JTextField(20);
//确认、取消按钮
protected JButton jb1 = new JButton("确认");
protected JButton jb2 = new JButton("取消");
//转账时转账账号标签
protected JLabel jLabel = new JLabel("请输入转账账号:");
//转账时转账账号文本框
protected JTextField jTextField = new JTextField(20);
//修改密码时新密码标签
protected JLabel jLabelCP = new JLabel("请输入新密码(只能为数字):");
//修改密码时新密码文本框
protected JTextField jTextFieldCP = new JTextField(20);
//提醒用户输入金额为100的倍数
private JLabel jle = new JLabel("( 提示:只能输入100的倍数(转账不算) )");
public CentreJFrame(String str){
super(str);
//判断要进行的操作
if(str.equals("转账"))
init1();
else if(str.equals("修改密码"))
init2();
else
init();
one();//最后调用共有
}
//取钱和取钱特有组件
private void init(){
//输入金额标签,设置字体,位置及大小
jl.setFont(FONT_SIZE_25);
jl.setBounds(100,100,200,100);
//输入金额文本框
jtf.setBounds(300,250,200,50);
//添加输入金额标签和输入金额文本框
jp.add(jl);
jp.add(jtf);
setJLE();
}
//转账特有组件
private void init1(){
init();
//输入账户标签
jLabel.setFont(FONT_SIZE_25);
jLabel.setBounds(100,10,200,40);
//输入账户文本
jTextField.setBounds(300,80,200,50);
//添加输入账户标签和输入账户文本
jp.add(jLabel);
jp.add(jTextField);
}
//修改密码特有组件
private void init2(){
//输入新密码标签
jLabelCP.setFont(FONT_SIZE_25);
jLabelCP.setBounds(50,100,400,70);
//输入新密码文本框
jTextFieldCP.setBounds(300,215,200,40);
//添加输入新密码标签和输入新密码文本框
jp.add(jLabelCP);
jp.add(jTextFieldCP);
}
//共有组件及操作
private void one(){
//按钮设置
jb1.setFont(FONT_SIZE_20);
jb2.setFont(FONT_SIZE_20);
jb1.setBounds(300,350,100,50);
jb2.setBounds(450,350,100,50);
jp.add(jb1);
jp.add(jb2);
jp.setBackground(Color.GREEN);
jb1.addActionListener(listener);
jb2.addActionListener(listener);
//添加到窗体
add(jp);
setVisible(true);
}
//设置提示
private void setJLE(){
jle.setFont(FONT_SIZE_10);
jle.setBounds(100,180,300,50);
jp.add(jle);
}
//创建监听器
private ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {//按钮被点击后
String actionCommand = e.getActionCommand();//获取按钮上的字
switch(actionCommand){
case "确认":
change();
break;
case "取消":
new WorkingJFrame();//创建功能界面
dispose();//关闭此界面
break;
}
}
};
//点击确认按钮执行的操作,子类重写覆盖实现各自功能
protected void change(){
}
//正则表达式判断输入是否为数字
protected boolean isNumber(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if(!isNum.matches())
return false;
return true;
}
}
package MyJFrame;
/**
* 取钱界面
* extends CentreJFrame
*/
public class QuMoneyJFrame extends CentreJFrame {
public QuMoneyJFrame(){
super("取钱");
}
protected void change(){
String s = jtf.getText();
if(isNumber(s)){
Double money = Double.parseDouble(s);
boolean b = atm.quMoney(money);
if(b){
showMessageDialog("请收好您的钱\n您的账户余额为:" + atm.getMoney1());
}
else
showMessageDialog("您输入有误" );
}
else
showMessageDialog("您输入有误" );
jtf.setText("");
}
}
package MyJFrame;
/**
* 存钱界面
* extends CentreJFrame
*/
public class CunMoneyJFrame extends CentreJFrame {
public CunMoneyJFrame(){
super("存钱");
}
protected void change(){
String s = jtf.getText();
if(isNumber(s)){
Double money = Double.parseDouble(s);
boolean b = atm.saveMoney(money);
if(b)
showMessageDialog("您的钱钱已存入\n您的账户余额为:" + atm.getMoney1());
else
showMessageDialog("您输入有误" );
}
else
showMessageDialog("您输入有误" );
jtf.setText("");
}
}
package MyJFrame;
/**
* 转账界面
* extends CentreJFrame
*/
public class GiveMoneyJFrame extends CentreJFrame {
public GiveMoneyJFrame(){
super("转账");
}
protected void change(){
String s = jTextField.getText();
boolean b = atm.anotherUser(s);
if(b){
//获取输入金额
String s1 = jtf.getText();
if(isNumber(s1)){//如果输入是数字
Double money = Double.parseDouble(s1);
atm.giveMoney(money);
showMessageDialog("钱已转入\n您的账户余额为:" + atm.getMoney1());
}
else
showMessageDialog("您输入有误" );
}
else
showMessageDialog("您输入有误" );
new WorkingJFrame();//创建功能界面
dispose();//关闭此界面
}
}
package MyJFrame;
/**
* 修改密码界面
* extends CentreJFrame
*/
public class ChangePasswordJFrame extends CentreJFrame{
public ChangePasswordJFrame(){
super("修改密码");
}
protected void change(){
String s = jTextFieldCP.getText();
if(isNumber(s)){
if(atm.changePassword(s))
showMessageDialog("密码修改成功");
else
showMessageDialog("密码修改失败");
}
else
showMessageDialog("您输入有误" );
new WorkingJFrame();//创建功能界面
dispose();//关闭此界面
}
}
mysql代码
CREATE DATABASE atm1;
CREATE TABLE atm1(
id INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(30),
PASSWORD VARCHAR(6),
money DOUBLE(6,2)
);
INSERT INTO atm1(id,uname,PASSWORD,money) VALUES(
NULL,
'张三',
'123',
0
);
INSERT INTO atm1(id,uname,PASSWORD,money) VALUES(
NULL,
'李四',
'456',
0
);
INSERT INTO atm1(id,uname,PASSWORD,money) VALUES(
NULL,
'王五',
'789',
0
);
SELECT * FROM atm1; # 查询语句
效果图
功能界面都可以实现,就是有点丑。
代码还有很多不总,可以改进的地方还有很多,可以用图片作为背景,类与类之间的关系可以更合理。。。
源代码和依赖的jar包下载地址