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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 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

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7天前
|
SQL 关系型数据库 MySQL
【Go语言专栏】使用Go语言连接MySQL数据库
【4月更文挑战第30天】本文介绍了如何使用Go语言连接和操作MySQL数据库,包括选择`go-sql-driver/mysql`驱动、安装导入、建立连接、执行SQL查询、插入/更新/删除操作、事务处理以及性能优化和最佳实践。通过示例代码,展示了连接数据库、使用连接池、事务管理和性能调优的方法,帮助开发者构建高效、稳定的Web应用。
|
5天前
|
SQL 数据可视化 关系型数据库
【MySQL-11】多表查询全解-【多表关系/内外自连接/子查询/多表查询案例链接】(可cv代码&案例演示)
【MySQL-11】多表查询全解-【多表关系/内外自连接/子查询/多表查询案例链接】(可cv代码&案例演示)
|
5天前
|
关系型数据库 MySQL Linux
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
|
5天前
|
SQL 关系型数据库 MySQL
【MySQL-5】DDL的数据库操作:查询&创建&删除&使用(可cv代码+演示图)
【MySQL-5】DDL的数据库操作:查询&创建&删除&使用(可cv代码+演示图)
|
5天前
|
SQL 关系型数据库 MySQL
【MySQL-1】理解关系型数据库&数据的数据模型
【MySQL-1】理解关系型数据库&数据的数据模型
|
6天前
|
Java 关系型数据库 测试技术
Java代码一键生成数据库文档(案例详解)
Screw是一个自动化数据库文档生成工具,能根据数据库表结构快速生成简洁、多格式(HTML、Word、Markdown)的文档,支持MySQL、MariaDB等多数据库。它使用Freemarker模板,允许用户自定义样式。依赖包括HikariCP数据库连接池和对应JDBC驱动。通过在Java代码或Maven插件中配置,可方便生成文档。示例代码展示了如何在测试用例中使用Screw。文档效果依赖于数据库中的表和字段注释。
|
7天前
|
关系型数据库 MySQL 数据库
Docker数据库Mysql
Docker数据库Mysql
|
7天前
|
存储 SQL 关系型数据库
mysql查询数据库表大小怎么操作
mysql查询数据库表大小怎么操作
|
7天前
|
关系型数据库 MySQL Java
datagrip连接mysql报错: No appropriate protocol (protocol is disabled or cipher suites are inappropriate
datagrip连接mysql报错: No appropriate protocol (protocol is disabled or cipher suites are inappropriate
|
7天前
|
关系型数据库 MySQL PHP
【PHP 开发专栏】PHP 连接 MySQL 数据库的方法
【4月更文挑战第30天】本文介绍了 PHP 连接 MySQL 的两种主要方法:mysqli 和 PDO 扩展,包括连接、查询和处理结果的基本步骤。还讨论了连接参数设置、常见问题及解决方法,如连接失败、权限和字符集问题。此外,提到了高级技巧如使用连接池和缓存连接信息以优化性能。最后,通过实际案例分析了在用户登录系统和数据管理中的应用。