题目:
设置一个银行简易操作,通过jdbc驱动连接数据库,之后对数据库中的account表进行操作 ,可以查询账户余额和进行转账(存款取款原理一样)(表结构如下)
代码思路:
在本题中,要求我们通过jdbc实现对数据库的访问,并操作和查询其中的数据。为了展示方便,在本程序中我使用窗体进行展示(如果对窗体不熟悉的,只看核心代码就行:select()方法和transfer()方法)。
核心代码思路:第一步,我们要对数据库进行连接,这个是我们操作数据库的基础(通过jdbc驱动即可连接),这一步如果遇见问题的话请检查驱动是否成功引用、连接的数据库信息是否拼写正确、url参数是否配置正确,大多数就这三个地方(细心一点,第一步一般不会出错);第二步:通过Connection的对象调用creatStatement()方法创建一个Statement的对象,因为我们需要通过Statement的对象调用executeQuery()方法和executeUpdate()方法来检索和修改数据库中的数据(具体操作可以看这两个方法的介绍);第三步:对传递过来的参数进行处理(转账功能为例):在转账功能中,需要传入参数:转出用户、转入用户、转款金额,该方法在获取到这些参数之后,首先调用executeQuery()方法对转出账户在数据库中进行检索,查看是否存在该账户或者其余额是否足以转账;如果满足条件,则通过executeUpdate()方法来对两个用户的余额进行修改(在此处有一个遗漏点:即未对转入用户判断其是否在数据库中,判断方法也很简单,我就偷个懒了);在这其中,如果没有遇见异常,则该方法返回true,若中间遇见异常或者有条件不满足,则返回false,通过对其返回值进行判断,来判定是否转账成功并对用户进行提示。
窗体代码思路(如果对实现窗体不感兴趣。跳过即可,使用核心代码,也可编译出一般在命令提示行交互的程序):在本道题目中,我设置了三个区域,分别放在三个JPanel的对象中,第一个区域为功能选择区,在该区域中,存在两个按钮,分别代表转账功能和查询功能,点击对应按钮可以跳到对应区域;第二个区域为查询功能区,该区域中有一个可以输入用户账号的文本框以及一个确认查询按钮,通过文本框输入账号,点击查询按钮即可,之后通过消息弹框展示查询结果;第三个区域为转账功能区,在该区域存在三个文本框来进行转出用户和转入用户以及转款金额的输入,之后点击按钮确认转账即可,之后也是通过消息弹框展示转账结果。
知识储备:
在该题目中,逻辑难度并不大,大家很容易就会有思路,主要可能是在一些实现方面不能很好的去处理,想要完整的实现该题目,需要具有一下知识储备:
1.java通过jdbc连接mysql数据库:如果要对数据库操作,能够连接数据库是第一步,如果这一步出问题,这个程序便无从说起,所以关于连接这方面的知识,要足够扎实;
2.会使用简单的SQL语句:在编写程序的时候,不一定已经系统的学习过数据库了,但是能够使用数据库的基本语句进行简单的增删改查,因为在这里涉及到对数据库语法的使用;
3.窗体布局的足够熟练:想要实现各个区域之间的转换,就要了解窗体的基本知识,并且能够熟练地使用各种布局及各种方法。
注:对于想练习数据库和窗体知识点的同学,这个题目是一个非常具有针对性的题目,首先这道题目在逻辑思维上不是那么有难度,大家可以不必考虑算法的难度,其次,这道题目涵盖的知识点很丰富,通过这道题,大家可以对其知识的熟练程度进行很好的巩固;最后,我在后面赋了完整的代码和运行结果,并且含有大量注释,如果遇见问题的话通过读代码应该可以解惑。如果对这个程序由更好的实现方法或者有什么不懂的都可以互相交流
代码
//主类
package Demo_03_Bank;
/**
* @ClassName 主类
* @Description TODO
* @Author 今夕河西
* @Date 2022-10-10 0:35
* @Version 1.0
**/
public class Main {
public static void main(String[] args) {
Window win = new Window();
win.setTitle("银行小功能");
win.setBounds(150,100,300,100);
}
}
//窗体类及核心代码类
package Demo_03_Bank;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
/**
* @ClassName 窗体类
* @Description TODO :设置一个银行简易操作,通过jdbc驱动连接数据库,之后对数据库中的account表进行操作
* 数据库中的account表进行操作,可以查询账户余额和进行转账(存款取款原理一样,不写了)
* @Author 今夕河西
* @Date 2022-10-10 0:35
* @Version 1.0
**/
public class Window extends JFrame implements ActionListener {
//设置组件
//功能区组件
JButton button_select; //查询功能
JButton button_transfer; //转账功能
JLabel label; //功能区提示
JPanel panel1; //功能区框架
//查询区组件
JTextField text1; //输入所要查询的账户
JButton button1; //查询按钮
JLabel label1_1; //组件说明--查询账户
JPanel panel2; //查询区框架
//转账区组件
JTextField text3; //填写转出用户账号
JTextField text4; //填写转入用户账号
JTextField text5; //转出金额
JLabel label2_1; //组件说明--转出账户
JLabel label2_2; //组件说明--转入账户
JLabel label2_3; //组件说明--转出金额
JButton button2; //转账按钮
JPanel panel3; //转账区框架
//数据库连接变量
Connection con; //连接数据库
Statement sql; //传递SQL语句
ResultSet rs; //结果集
Window () {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
//功能区:
label = new JLabel("功能选择");
button_select = new JButton("查询");
button_transfer = new JButton("转账");
panel1 = new JPanel();
//将组建添加到panel1中
panel1.add(label);
panel1.add(button_select);
panel1.add(button_transfer);
add(panel1, BorderLayout.NORTH); //功能区直接展示
button_select.addActionListener(this); //添加事件
button_transfer.addActionListener(this);
//查询区:
label1_1 = new JLabel("输入账户号码");
text1 = new JTextField(12);
button1 = new JButton("确认查询");
panel2 = new JPanel();
//将组建添加到panel2中,注意此时不要将其添加到窗口中,待触发事件后再进行添加
panel2.add(label1_1);
panel2.add(text1);
panel2.add(button1);
button1.addActionListener(this);
//转账区:
label2_1 = new JLabel("转出账号");
text3 = new JTextField(12);
label2_2 = new JLabel("转入账户");
text4 = new JTextField(12);
label2_3 = new JLabel("转出金额");
text5 = new JTextField(6);
button2 = new JButton("确认转账");
panel3 = new JPanel();
//将组建添加到panel3中,注意此时不要将其添加到窗口中,待触发事件后再进行添加
panel3.add(label2_1);
panel3.add(text3);
panel3.add(label2_2);
panel3.add(text4);
panel3.add(label2_3);
panel3.add(text5);
panel3.add(button2);
button2.addActionListener(this);
}
/*
*@ auther 今夕河西
*@ Description //TODO 转账:将用户account1的钱转向account2
*@ Param account1:用户1的账户
*@ Param account2:用户2的账户
*@ Param money:用户1向用户2转的钱
*@ return :转账成功返回true,转账失败返回false
**/
private boolean transfer (String account1, String account2,double money) {
try {
Class.forName("com.mysql.cj.jdbc.Driver"); //新版需加.cj.
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_a?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false", "root", "manager");
} catch (Exception e) {
System.out.println("ERROR:"+e);
}
//连接数据库成功,之后对数据库进行操作
if(con == null) return false; //连接为空,则结束程序
try {
sql = con.createStatement();
rs = sql.executeQuery("select money from account where accountnumber =" + account1 );
while (rs.next()) {
double moneys = rs.getDouble(1);
if (moneys > money) { //余额充足
String sqlstr1 = "update account set money = money - " + money + "where accountnumber = " + account1; //从用户1中转出
String sqlstr2 = "update account set money = money + " + money + "where accountnumber = " + account2; //转入到用户2中
int ok = sql.executeUpdate(sqlstr1);
int ok2 = sql.executeUpdate(sqlstr2);
return true; //对数据库操作完成,直接返回真值
} else {
return false; //金额不足,转账失败
}
}
return false; //没有进入while循环,代表没有该用户
} catch (SQLException e) {
return false;
}
}
/*
*@ auther 今夕河西
*@ Description //TODO 转账:将用户account1的钱转向account2
*@ Param account1:用户的账户
*@ return : 返回查询到的金额,查询失败返回-1
**/
private double select (String account1) {
double money = -1; //设定初始值为-1,后期通过对值进行判断来判定是否检索成功
try {
Class.forName("com.mysql.cj.jdbc.Driver"); //新版需加.cj.
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_a?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false", "root", "manager");
} catch (Exception e) {
System.out.println("ERROR:"+e);
}
//连接数据库成功,之后对数据库进行操作
if(con == null) return -1; //连接为空,则结束程序
try {
sql = con.createStatement();
rs = sql.executeQuery("select money from account where accountnumber =" + account1 ); //查询金额
while (rs.next()) { //查询到数据
money = rs.getDouble(1);
}
} catch (Exception exp) {
return -1;
}
return money;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button_select) { //选择查询功能,则将查询功能进行添加,并重新设置窗体格式
remove(panel3); //将转账功能移除
add(panel2,BorderLayout.CENTER); //将查询功能加入
setSize(500,150);
setTitle("查询功能区");
validate();
} else if (e.getSource() == button_transfer) { //选择转账功能,则将转账功能进行添加,并重新设置窗体格式
remove(panel2);
add(panel3,BorderLayout.CENTER);
setSize(700,150);
setTitle("转账功能区");
validate();
} else if (e.getSource() == button1) { //点击查询,调用select方法并展示结果
String account = text1.getText();
double balance = select(account);
if (balance == -1) { //查询失败
JOptionPane.showMessageDialog(this,"查询失败,请检查账户是否" +
"输入正确","查询失败",JOptionPane.WARNING_MESSAGE);
} else {
JOptionPane.showMessageDialog(this,"当前余额为" +
balance,"查询成功",JOptionPane.WARNING_MESSAGE);
}
} else if (e.getSource() == button2) {
String account1 = text3.getText();
String account2 = text4.getText();
double money = 0;
try {
money = Double.parseDouble(text5.getText());
} catch (Exception exp) {
JOptionPane.showMessageDialog(this,"转账失败,金额输入错误!" +
"","转账失败",JOptionPane.WARNING_MESSAGE);
}
if (transfer(account1,account2,money)) {
JOptionPane.showMessageDialog(this,"转账成功" +
"","转账成功",JOptionPane.WARNING_MESSAGE);
} else {
JOptionPane.showMessageDialog(this,"转账失败,请检查账户输入是否正确!" +
"","转账失败",JOptionPane.WARNING_MESSAGE);
}
}
}
}
运行截图:
运行之前表中数据:
运行的初始界面:功能选择区域
点击查询按钮进入查询功能区:
输入参数:
点击确认查询按钮:
确定退出后,点击转账按钮,进入转账功能区:
输入参数(注意数据和用户,看接下来的变化):
点击确认转账按钮,转账成功(注意对比数据变化):