Java——Demo使用GUI并连接数据库实现购买火车票<MySQL>

本文涉及的产品
RDSClaw,2核4GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: Java——Demo使用GUI并连接数据库实现购买火车票<MySQL>

绪:

Java使用多线程和GUI实现购买火车票<集合>

之前写了一个用Map集合来存储车票和顾客的信息,有点简陋,不过很基础。所以在上一次的基础上加了点东西,连接了数据库。下面是用到的环境


配置环境

  1. JDK1.8
  2. MySQL 8.0
  3. JDBC驱动 8.0.22
  4. Apache-DBUtils的API 1.6
  5. Druid驱动包1.1.10

项目要求

  1. 文本文件提供票的信息,车次、票价、始发站终点站、票数
  2. 启动程序,首先读取文件,放入TextArea中,如果车次较多,那么需要加滚动条(上述两步骤,用到的是文件读写IO)
  3. 输入车次,查找该车次,并显示信息
  1. 如何在文本域中找出相关信息,并且读出这一条信息——字符串操作
  1. 找到车次了,输入购买张数,点击购买,弹出新的窗口——新的窗口是启动了一个线程——多线程
  2. 在购买界面,显示购买车次的信息,和顾客进行确认。并且提供身份证信息
  1. 如果买多张,那么这些身份证信息,先保存到集合中(map),遍历集合,给每个身份证购买一张票
  1. 输出购买信息

项目分析

因为这次要连接数据库操作,那么就需要建立对应的表存储信息,

首先了解两种思想

  • 面向接口编程的思想
  • ORM思想(object relational mapping)
  • 一个数据表对应一个java类
  • 表中的一条记录对应java类的一个对象
  • 表中的一个字段对应java类的一个属性

即数据库中的一个数据表对应着java的javabean类


sql是需要结合列名和表的属性名来写。注意起别名。


1. MySQL数据库

  1. 【ticket数据库】
  2. 【tickets表】存储所有车票信息
  3. 【person表】存储所有购买车票的顾客信息
  4. 【administrator表】存储管理员的账号密码

2. GUI各个窗口的功能

根据上一次的经验,这次又要连接数据库,所以我分了下功能


主窗口【Window.java】

  1. 文本文件提供票的信息,车次、票价、始发站终点站、票数
  2. 启动程序,首先读取文件,放入TextArea中,如果车次较多,那么需要加滚动条
  3. 查询车票

购买窗口【PayWindow.java】

  1. 显示提交的顾客信息
  2. 根据提交的顾客信息购买车票

管理员登录窗口【Login.java】

  1. 管理员输入账号密码登录

修改车票窗口【UpadateTicketWindow.java】

修改车票窗口【UpadateTicketWindow.java】是用于 后台对车票信息的管理,包含以下功能

  1. 插入单个车票
  2. 修改单个车票
  3. 批量插入车票
  4. 批量修改车票
  5. 删除单个车票
  6. 批量删除信息(所有车票信息,所有历史购买信息)

因为拥有插入,修改,删除功能,我又想做的好看点,便于与用户交互,就每个又分别写了个窗口


加载登录窗口【LoadLogin.java】在管理员登录窗口【Login.java】和修改车票窗口【UpadateTicketWindow.java】之间加入了一个登录进度条窗口【LoadLogin.java】没什么用,只是为了好看

  1. 显示登录进度条

代码实现

既然了解了ORM思想,那么数据库有3个数据表【tickets表】,【person表】,【administrator表】,所以对应的需要建3个类【tickets.java】,【person.java】,【administrator.java】


JavaBean类

1.【tickets.java】

publicclassTickets {
privateStringname; // 车票名privateStringstart; // 起始站privateStringend; // 终点站privateintnumber; // 数量privatedoubleprice; // 价格publicTickets(Stringname, Stringstart, Stringend, doubleprice, intnumber) {
super();
this.name=name;
this.start=start;
this.end=end;
this.number=number;
this.price=price;
    }
publicStringgetName() {
returnname;
    }
publicvoidsetName(Stringname) {
this.name=name;
    }
publicStringgetStart() {
returnstart;
    }
publicvoidsetStart(Stringstart) {
this.start=start;
    }
publicStringgetEnd() {
returnend;
    }
publicvoidsetEnd(Stringend) {
this.end=end;
    }
publicintgetNumber() {
returnnumber;
    }
publicvoidsetNumber(intnumber) {
this.number=number;
    }
publicdoublegetPrice() {
returnprice;
    }
publicvoidsetPrice(doubleprice) {
this.price=price;
    }
publicTickets() {
super();
    }
@OverridepublicStringtoString() {
return"Ticket [name="+name+", start="+start+", end="+end+", number="+number+", price="+price+"]";
    }
}



2.【person.java】

importjava.sql.Date;
importjava.sql.Timestamp;
publicclassPerson {
privateStringname; // 姓名privateStringIDCard; // 身份证号privateStringticketname; // 车票名privateStringstart; // 起始站privateStringend; // 终点站privatedoubleprice; // 车票的价钱privateTimestampdate;// 时间戳publicPerson(Stringname, StringiDCard, Stringticketname, Stringstart, Stringend, doubleprice,
Timestampdate) {
super();
this.name=name;
IDCard=iDCard;
this.ticketname=ticketname;
this.start=start;
this.end=end;
this.price=price;
this.date=date;
    }
publicTimestampgetDate() {
returndate;
    }
publicvoidsetDate(Timestampdate) {
this.date=date;
    }
publicPerson() {
super();
    }
publicPerson(Stringname, StringiDCard) {
super();
this.name=name;
IDCard=iDCard;
    }
publicPerson(Stringname, StringiDCard, Stringticketname, Stringstart, Stringend, doubleprice) {
super();
this.name=name;
this.IDCard=iDCard;
this.ticketname=ticketname;
this.start=start;
this.end=end;
this.price=price;
    }
publicStringgetName() {
returnname;
    }
publicvoidsetName(Stringname) {
this.name=name;
    }
publicStringgetIDCard() {
returnIDCard;
    }
publicvoidsetIDCard(StringiDCard) {
IDCard=iDCard;
    }
publicStringgetTicketname() {
returnticketname;
    }
publicvoidsetTicketname(Stringticketname) {
this.ticketname=ticketname;
    }
publicStringgetStart() {
returnstart;
    }
publicvoidsetStart(Stringstart) {
this.start=start;
    }
publicStringgetEnd() {
returnend;
    }
publicvoidsetEnd(Stringend) {
this.end=end;
    }
publicdoublegetPrice() {
returnprice;
    }
publicvoidsetPrice(doubleprice) {
this.price=price;
    }
@OverridepublicStringtoString() {
return"Person [name="+name+", IDCard="+IDCard+", ticketname="+ticketname+", start="+start+", end="+end+", price="+price+"]";
    }
}

3.【administrator.java】

publicclassAdministrator {
privateStringusername;
privateStringpassword;
publicAdministrator(Stringusername, Stringpassword) {
super();
this.username=username;
this.password=password;
    }
publicAdministrator() {
super();
    }
publicStringgetUsername() {
returnusername;
    }
publicvoidsetUsername(Stringusername) {
this.username=username;
    }
publicStringgetPassword() {
returnpassword;
    }
publicvoidsetPassword(Stringpassword) {
this.password=password;
    }
@OverridepublicStringtoString() {
return"Administrator [username="+username+", password="+password+"]";
    }
}

窗口


一、 主窗口【Window.java】

主窗口的布局和上次没什么改变,只是加了智能购票系统后台管理按钮

6c3693a878f5e9aaf43e974917b2578c.png

事件监听

因为窗口启动时显示【tickets表】的所有车票信息,查找也需要显示车票信息,刷新也要显示车票信息,因此将显示车票信息写成了一个方法,仅需要传入用于显示信息的TextArea, 和要执行的sql语句,用于需要输出车票信息时调用,方法如下:

// 打印tickets数据表中的所有车票信息publicvoidloadticket(JTextAreatextArea, Stringsql) {
Connectioncon=null;
try {
// 获取连接con=source.getConnection();
BeanListHandler<Tickets>ticketbean=newBeanListHandler<Tickets>(Tickets.class);
//调用QueryRunner类的方法执行sql语句,返回ticketbean组成的集合List<Tickets>ticketlist=runner.query(con, sql, ticketbean);
//迭代器遍历集合,输出信息Iterator<Tickets>iter=ticketlist.iterator();
Stringticstr="";
while (iter.hasNext()) {
Ticketsticket=iter.next();
ticstr+=" "+ticket.getName() +"\t"+ticket.getStart() +"\t"+ticket.getEnd() +"\t"+ticket.getPrice() +"\t"+ticket.getNumber() +"\n";
            }
textArea.setText(ticketload+ticstr);
        } catch (SQLExceptione1) {
e1.printStackTrace();
        } finally {
// 释放连接DbUtils.closeQuietly(con);
        }
    }
1. 窗口启动,读取【tickets表】,TextArea显示

窗口加载事件【windowOpened】,读取ticket数据库中,【tickets表】中存储的所有车票信息,TextArea显示

// 窗口加载事件addWindowListener(newWindowAdapter() {
@OverridepublicvoidwindowOpened(WindowEvente) {
//调用loadticket()方法Stringsql="SELECT * FROM tickets";
loadticket(textArea, sql);
            }
        });

2. 查询按钮

根据输入的信息,模糊查询【tickets表】,TextArea显示查询的结果

// 查找按钮button_search.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
//获取用户输入的信息Stringtext=searchText.getText();
//调用loadticket()方法Stringsql="SELECT * FROM tickets WHERE NAME LIKE '%"+text+"%'";
loadticket(textArea_1, sql);
            }
        });

3. 刷新按钮

更新TextArea显示的信息

// 刷新按钮shuaxin.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
//调用loadticket()方法Stringsql="SELECT * FROM tickets";
loadticket(textArea, sql);
            }
        });

4. 购买按钮

打开购买窗口【PayWindow.java】

// 购买按钮button_buy.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEvente) {
Connectioncon=null;
try {
//获取 Druid连接池的连接con=source.getConnection();
PayWindowpw=newPayWindow(con);
newThread(pw).start();
                } catch (SQLExceptione1) {
e1.printStackTrace();
                }
            }
        });

5. 智能购票系统后台管理按钮

打开管理员登录窗口【Login.java】

/*** 后台*/btnNewButton.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
Connectioncon=null;
try {
// 获取Druid连接池的连接con=source.getConnection();
Loginframe=newLogin(con);
newThread(frame).start();
                } catch (SQLExceptione) {
e.printStackTrace();
                }
            }
        });

二、购买窗口【PayWindow.java】

购买窗口也在之前的基础上加了显示历史购买车票信息每日一言(每3s刷新一次)

26403edbde603cc6fbb5f51f6f79fb24.png


事件监听

因为窗口加载时要显示历史购买信息,以及每次下单成功后自动更新历史购买的信息,因此也写了一个方法,需要传一个Connection连接和要显示的JTextArea

publicvoidshow(Connectioncon, JTextAreatextArea) {
// 遍历输出【person表】中的信息Stringli="";
try {
BeanListHandler<Person>personbeanlist=newBeanListHandler<Person>(Person.class);
Stringsql="SELECT * FROM person ORDER BY ticketname;";
List<Person>personlist=runner.query(con, sql, personbeanlist);
Iterator<Person>iter=personlist.iterator();
while (iter.hasNext()) {
Personperson=iter.next();
li+="  "+person.getName() +"       "+person.getIDCard().substring(0, 6) +"******"+person.getIDCard().substring(14) +"\t"+person.getTicketname() +"  "+person.getStart()
+" "+person.getEnd() +" "+person.getPrice() +"   "+person.getDate() +"\n";
            }
textArea.setText(personlist3+li);
        } catch (SQLExceptione1) {
e1.printStackTrace();
        }
    }

1. 窗口启动,TextArea显示【person表】中的信息,每日一言

窗口启动,显示历史购买信息,和每日一言(每3s刷新)

@OverridepublicvoidwindowOpened(WindowEvente) {
/*** 输出personMap集合的信息*/show(con, textArea_1);
//List加载每日一言文件strList.clear();
FileReaderfr=null;
BufferedReaderbr=null;
try {
fr=newFileReader("src//每日一言");
br=newBufferedReader(fr);
Stringstr=null;
while ((str=br.readLine()) !=null) {
strList.add(str);
                    }
                } catch (Exceptione1) {
e1.printStackTrace();
                } finally {
                }
// 定时显示每日一言Timertimer=newTimer();
timer.schedule(newTimerTask() {
@Overridepublicvoidrun() {
Randomrand=newRandom();
intnextInt=rand.nextInt(strList.size() -1);
lblNewLabel.setText(strList.get(nextInt));
                    }
                }, 1000, 3000);//初始1s定时,以后定时3s            }

2. 提交信息按钮

将输入的姓名和身份证号添加到集合,并显示在TextArea中,根据提交信息的数量来决定购票的数量

// 提交信息btnNewButton_subbmit.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEvente) {
Stringname=textField_name.getText();
Stringidcard=textField_IDCard.getText();
Stringselect="select IDCard from person where IDCard=?";
// 如果两个文本框不为空则添加信息到队列if (!"".equals(name) &&!"".equals(idcard)) {
if (personMap.containsKey(idcard)) {
intn=JOptionPane.showConfirmDialog(null, "提交信息已存在,是否覆盖", "信息提示", JOptionPane.YES_NO_OPTION);
if (n==0) {
personMap.put(idcard, newPerson(name, idcard));
                        }
                    } else {
// 用获取到的姓名和身份证号生成对象,添加到存储顾客对象的Map集合中personMap.put(idcard, newPerson(name, idcard));
                    }
Stringli="";
// 遍历Map集合,获取集合中顾客的所有信息Set<Map.Entry<String, Person>>set=personMap.entrySet();
Iterator<Entry<String, Person>>setItor=set.iterator();
while (setItor.hasNext()) {
Personperson=setItor.next().getValue();
// 将顾客的所有的信息拼接成字符串li+="  "+person.getName() +"       "+person.getIDCard().substring(0, 6) +"******"+person.getIDCard().substring(14) +"\n";
                    }
// 5.textArea显示拼接的字符串textArea.setText(personlist1+li);
                } else {
JOptionPane.showMessageDialog(null, name+idcard+"信息不完整", name+idcard, 0);
                }
            }
        });
    }

三、管理员登录窗口【Login.java】

由主窗口【Window.java】点击【智能购票系统后台管理按钮】打开,用户输入用户名和密码

38a47c0a02ff1271533aa816acaea9c0.png


事件监听

1. 登录按钮

获取输入的用户名和密码,显示进度条

//登录点击按钮,进行登录btnNewButton.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
Stringname=textField.getText();
Stringpassword=textField_1.getText();
try {
//判断用户名和密码是否为空if (!"".equals(name) &&!"".equals(password)) {
//启动登录进度条,传入输入的用户名和密码Loadloginload=newLoadlogin(con, name, password);
newThread(load).start();
//销毁窗口dispose();
                    } else {
JOptionPane.showMessageDialog(null, "请输入信息", "ERROR", 0);
                    }
                } catch (Exceptione) {
e.printStackTrace();
                }
            }
        });

四、加载登录窗口【LoadLogin.java】

一个进度条,同时拿获取的用户名和密码和数据库中的【administrator表】进行信息比对

如果都存在则登录成功,进入修改车票窗口【UpadateTicketWindow.java】

如果失败,则返回管理员登录窗口【Login.java】


事件监听

显示进度条,同时拿获取的用户名和密码和数据库中的【administrator表】进行信息比对

addWindowListener(newWindowAdapter() {
@OverridepublicvoidwindowOpened(WindowEventarg0) {
//定时器,3sTimertimer=newTimer();
timer.schedule(newTimerTask() {
@Overridepublicvoidrun() {
Stringsql="SELECT password FROM administrator WHERE username=?";
BeanHandler<Administrator>bh=newBeanHandler<Administrator>(Administrator.class);
Administratoradmin=null;
try {
//进行数据库查询admin=runner.query(con, sql, bh, name);
//如果用户存在并且输入的用户名和密码正确if (admin!=null&&admin.getPassword().equals(password)) {
//如果存在,则进度条显示登录成功jpg.setString("登录成功");
Thread.sleep(1000);
dispose();
//显示修改车票窗口【UpadateTicketWindow.java】UpadateTicketWindowupadateTicketWindow=newUpadateTicketWindow(con,name);
newThread(upadateTicketWindow).start();
                            } else {
//如果不存在,则进度条显示登录失败jpg.setString("登录失败");
Thread.sleep(1000);
dispose();
//返回管理员登录窗口【Login.java】Loginlogin=newLogin(con);
newThread(login).start();
                            }
                        } catch (Exceptione1) {
e1.printStackTrace();
                        }
                    }
                }, 3000);
            }
        });



五、修改车票窗口【UpadateTicketWindow.java】

对信息的单个增删改和批量增删改,每个按钮对应一种操作

dbb2414364a2e5fd64fdfdd3caaae4c3.png


事件监听

批量操作涉及到的公用方法,【JFileChooser】选择文件,【IO流】读取文件

/*** 选择文件,读取文件信息,存放到ticList*/publicListselcetfile() {
FileReaderfr=null;
BufferedReaderbr=null;
try {
// 打开文件选择器JFileChooserjfc=newJFileChooser();
FileFilterfilter=newFileNameExtensionFilter("Text file", "txt");
// 过滤txt文件jfc.setAcceptAllFileFilterUsed(false);
jfc.addChoosableFileFilter(filter);
jfc.showOpenDialog(null);
Filefile=jfc.getSelectedFile();
if (file!=null) {
List<Tickets>ticList=newArrayList<Tickets>();
fr=newFileReader(file);
br=newBufferedReader(fr);
Stringstr=null;
//读取文件每一行,分析,并创建ticket对象存储到 List集合while ((str=br.readLine()) !=null) {
String[] split=str.split("\t");
Ticketstic=newTickets(split[0], split[1], split[2], Double.parseDouble(split[3]),
Integer.parseInt(split[4]));
ticList.add(tic);
                }
//返回添加数据之后的ticListreturnticList;
            }
        } catch (Exceptione) {
e.printStackTrace();
        } finally {
try {
if (br!=null)
br.close();
            } catch (IOExceptione1) {
e1.printStackTrace();
            }
try {
if (fr!=null)
fr.close();
            } catch (IOExceptione1) {
e1.printStackTrace();
            }
        }
returnnull;
    }

1. 显示当前登录用户

窗口启动,则显示目前登录的管理员用户信息

@OverridepublicvoidwindowOpened(WindowEventarg0) {
lblNewLabel_3.setText(name);
            }

2. 插入单个车票

因为插入单个车票涉及了车票的各种信息,所以加了一个窗口【InsertWindow.java】

点击按钮则启动【InsertWindow.java】窗口,让用户来添加信息

/*** 添加车票信息*/Button_insertOne.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEvente) {
InsertWindowiw=newInsertWindow(con);
newThread(iw).start();
            }
        });

3.修改单个车票

和插入单个车票操作类似,涉及车票的信息,加了一个修改窗口【updateWindow.java】

点击按钮则启动【updateWindow.java】窗口,让用户来输入修改的信息,根据车次名修改

// 修改单个数据Button_updateOne.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
updateWindowupdateWindow=newupdateWindow(con);
newThread(updateWindow).start();
            }
        });
4.批量插入车票

一次性插入多个车票信息,原理是读取并插入【车次.txt文件】中的所有车票信息


当然了,添加过程中,使用的是【DBUtils】提供的batch批量方法。考虑到了批量插入中途又可能会出现错误,加入了事务回滚,如果中途出现错误,则数据库数据回滚到上次提交之后的数据,因为数据库一旦提交则不可重现,所以需要关闭数据库的自动提交

// 批量插入Button_BatchInset.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEvente) {
Stringinsert="INSERT INTO tickets(name,start,end,price,number) VALUES(?,?,?,?,?)";
try {
//关闭事务自动提交con.setAutoCommit(false);
//调用selcetfile()读取文件,加载到集合List<Tickets>ticList=selcetfile();
String[][] strss=newString[ticList.size()][5];
for (inti=0; i<ticList.size(); i++) {
Ticketstic=ticList.get(i);
strss[i][0] =tic.getName();
strss[i][1] =tic.getStart();
strss[i][2] =tic.getEnd();
strss[i][3] =tic.getPrice() +"";
strss[i][4] =tic.getNumber() +"";
                    }
runner.batch(con, insert, strss);
//事务手动提交con.commit();
//开启事务自动提交con.setAutoCommit(true);
JOptionPane.showMessageDialog(null, "批量添加成功", "批量添加", 1);
                } catch (Exceptione1) {
try {
con.rollback();
                    } catch (SQLExceptione2) {
e2.printStackTrace();
                    }
                }
            }
        });

5. 批量修改车票

一次性修改文件存储的车次信息,读取【修改的车次.txt文件】中的所有车票信息,根据车次名修改。


和批量插入一样,修改过程中,使用的是【DBUtils】提供的batch批量方法。考虑到了批量修改中途又可能会出现错误,加入了事务回滚,如果中途出现错误,则数据库数据回滚到上次提交之后的数据,因为数据库一旦提交则不可重现,所以需要关闭数据库的自动提交

// 批量修改Button_updatemore.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
// 修改Stringupdate="UPDATE tickets SET START=?,END=?,price=?,NUMBER=? WHERE NAME=?";
// runner.btry {
// 关闭事务自动提交con.setAutoCommit(false);
// 读取文件,信息存到ticListList<Tickets>ticList=selcetfile();
// 将车票的信息存储到二维数组,String[][] strss=newString[ticList.size()][5];
for (inti=0; i<ticList.size(); i++) {
Ticketstic=ticList.get(i);
strss[i][0] =tic.getStart();
strss[i][1] =tic.getEnd();
strss[i][2] =tic.getPrice() +"";
strss[i][3] =tic.getNumber() +"";
strss[i][4] =tic.getName();
                    }
// QueryRunner,batch批量执行runner.batch(con, update, strss);
// 事务提交con.commit();
// 开启事务自动提交con.setAutoCommit(true);
JOptionPane.showMessageDialog(null, "批量修改成功", "批量修改", 1);
                } catch (Exceptione1) {
e1.printStackTrace();
// JOptionPane.showMessageDialog(null, "批量修改失败", "批量修改", 0);try {
// 失败则事务回滚con.rollback();
                    } catch (SQLExceptione2) {
e2.printStackTrace();
                    }
                }
            }
        });

6. 删除单个车票

删除单个车票比较简单,根据用户输入的车次名删除即可,因此选择了直接弹出对话框,用户输入即可

472808099f1ca0e9e99eb0fd663bcc54.png

/*** 删除单个信息按钮*/Button_deleteOne.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
try {
//弹出消息对话框,获取用户输入的信息StringinputDialog=JOptionPane.showInputDialog("删除指定车次");
if (inputDialog!=null) {
Stringsql="DELETE FROM tickets WHERE NAME=?";
runner.update(con, sql, inputDialog);
JOptionPane.showMessageDialog(null, "删除成功", "删除", 1);
                    }
                } catch (Exceptione) {
e.printStackTrace();
                }
            }
        });

7. 删除所有车票

考虑到涉及到数据库的两个表,【tickets表】和【person表】,因此加了一个窗口【deleteWindow】

点击按钮弹出【deleteWindow】窗口

/*** 删除所有信息*/Button_deletemore.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEvente) {
deleteWindowframe=newdeleteWindow(con);
newThread(frame).start();
            }
        });

8. 超链接

点击则用本地浏览器打开链接

// 点击打开超链接lblNewLabel_1.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
try {
URIurl=newURI("https://blog.csdn.net/qq_20185737");
Desktop.getDesktop().browse(url);
                } catch (Exceptione) {
e.printStackTrace();
                }
            }
        });

六、添加单个车票窗口【InsertWindow.java】

布局就是用户可以输入要添加车票的各种信息

d5049e8b3e5818062d2d60aabde6348f.png


事件监听

1.添加车票

根据输入的车票信息添加到数据库【tickets表】中

// 点击添加车票InsetButton.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
// 判断信息是否输入完整if ("".equals(text_name.getText()) ||"".equals(text_start.getText()) ||"".equals(text_end.getText())
||"".equals(text_number.getText()) ||"".equals(text_price.getText())) {
JOptionPane.showMessageDialog(null, "信息不完整", "Warning", 0);
                } else {
try {
// 插入语句Stringinsert="INSERT INTO tickets(name,start,end,price,number) VALUES(?,?,?,?,?)";
Stringselect="select name from tickets where name=?";
// 获取车票信息Stringname=text_name.getText();
Stringstart=text_start.getText();
Stringend=text_end.getText();
intnumber=Integer.parseInt(text_number.getText());
doubleprice=Double.parseDouble(text_price.getText());
// 实例化QueryRunner对象,获取查询语句返回的结果,根据结果来判断车次是否存在BeanHandler<String>bh=newBeanHandler<String>(String.class);
Stringgetname=runner.query(con, select, bh, name);
if (getname!=null) {
// 车次如果已存在则弹出消息框提示用户是否覆盖inta=JOptionPane.showConfirmDialog(null, "车次信息插入失败,已经存在该车次,如果要继续插入则覆盖原有信息", "Warning",
JOptionPane.YES_NO_OPTION);
if (a==0) {
Stringupdate="UPDATE tickets SET START=?,END=?,price=?,NUMBER=? WHERE NAME=?";
runner.update(con, update, start, end, price, number, name);
JOptionPane.showMessageDialog(null, name+"车次信息已修改", "修改结果", 1);
                            }
                        } else {
// 车次不存在则插入信息runner.update(con, insert, name, start, end, price, number);
JOptionPane.showMessageDialog(null, name+"车次信息已插入", "", 1);
                        }
                    } catch (Exceptione) {
e.printStackTrace();
                    }
                }
            }
        });

七、修改单个车票窗口【updateWindow.java】

布局就是用户输入要修改车票的各种信息,

8d9791b049ec411e2ab592298380afba.png


事件监听

1.修改

根据车次名称修改【tickets表】中的数据

// 点击输入修改信息InsetButton.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEventarg0) {
// 判断信息是否输入完整if ("".equals(text_name.getText()) ||"".equals(text_start.getText()) ||"".equals(text_end.getText())
||"".equals(text_number.getText()) ||"".equals(text_price.getText())) {
JOptionPane.showMessageDialog(null, "信息不完整", "Warning", 0);
                } else {
try {
Stringselect="select name from tickets where name=?";
// 获取车票信息Stringname=text_name.getText();
Stringstart=text_start.getText();
Stringend=text_end.getText();
intnumber=Integer.parseInt(text_number.getText());
doubleprice=Double.parseDouble(text_price.getText());
// 实例化QueryRunner对象,获取查询语句返回的结果,根据结果来判断车次是否存在BeanHandler<String>bh=newBeanHandler<String>(String.class);
Stringgetname=runner.query(con, select, bh, name);
if (getname==null) {
// 车次如果已存在则弹出消息框提示用户是否覆盖JOptionPane.showMessageDialog(null, "车次信息修改失败,不存在该车次,请插入信息后修改", "修改结果", 0);
                        } else {
// 修改语句Stringupdate="UPDATE tickets SET START=?,END=?,price=?,NUMBER=? WHERE NAME=?";
runner.update(con, update, start, end, price, number, name);
JOptionPane.showMessageDialog(null, name+"车次信息已修改", "修改结果", 1);
                        }
                    } catch (Exceptione) {
e.printStackTrace();
                    }
                }
            }
        });

八、删除所有车票窗口【deleteWindow.java】

清空数据库中对应的表的所有数据

3aab10fd8abaac7fbec1b7632781a1cd.png


事件监听

1.清空所有车票信息

删除数据库【tickets表】中的所有数据

btnNewButton.addMouseListener(newMouseAdapter() {
@OverridepublicvoidmouseClicked(MouseEvente) {
try {
inta=JOptionPane.showConfirmDialog(null, "是否要删除所有数据", "Warning",
JOptionPane.YES_NO_OPTION);
if(a==0) {
Stringsql="delete from tickets";
runner.update(con, sql);
JOptionPane.showMessageDialog(null, "所有车票信息已删除", "删除结果", 1);
                    }
                } catch (Exceptione1) {
e1.printStackTrace();
                } 
            }
        });

DEMO源码

Java——Demo智能火车票购票系统源码.zip

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
7月前
|
SQL Java 关系型数据库
Java连接MySQL数据库环境设置指南
请注意,在实际部署时应该避免将敏感信息(如用户名和密码)硬编码在源码文件里面;应该使用配置文件或者环境变量等更为安全可靠地方式管理这些信息。此外,在处理大量数据时考虑使用PreparedStatement而不是Statement可以提高性能并防止SQL注入攻击;同时也要注意正确处理异常情况,并且确保所有打开过得资源都被正确关闭释放掉以防止内存泄漏等问题发生。
322 13
|
9月前
|
人工智能 Java 关系型数据库
Java的时间处理与Mysql的时间查询
本文总结了Java中时间与日历的常用操作,包括时间的转换、格式化、日期加减及比较,并介绍了MySQL中按天、周、月、季度和年进行时间范围查询的方法,适用于日常开发中的时间处理需求。
170 0
|
11月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
501 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
SQL NoSQL 关系型数据库
超强数据库管理软件推荐-没有之一-还在用Navicat管理本地数据库的吗?还在为Navicat寻求绿色版或者购买正版的费用望而却步吗?DBeaver让你解决所有数据库本地编写问题-优雅草央千澈-DBeaver下载和安装
超强数据库管理软件推荐-没有之一-还在用Navicat管理本地数据库的吗?还在为Navicat寻求绿色版或者购买正版的费用望而却步吗?DBeaver让你解决所有数据库本地编写问题-优雅草央千澈-DBeaver下载和安装
1085 18
超强数据库管理软件推荐-没有之一-还在用Navicat管理本地数据库的吗?还在为Navicat寻求绿色版或者购买正版的费用望而却步吗?DBeaver让你解决所有数据库本地编写问题-优雅草央千澈-DBeaver下载和安装
|
自然语言处理 Java 关系型数据库
Java mysql根据很长的富文本如何自动获取简介
通过使用Jsoup解析富文本并提取纯文本,然后根据需要生成简介,可以有效地处理和展示长文本内容。该方法简单高效,适用于各种应用场景。希望本文对您在Java中处理富文本并生成简介的需求提供实用的指导和帮助。
279 9
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
921 26
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
597 1
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
432 2