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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
10天前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:详细步骤与最佳实践指南ali01n.xinmi1009fan.com
随着Web开发技术的不断进步,ASP.NET已成为一种非常流行的Web应用程序开发框架。在ASP.NET项目中,我们经常需要与数据库进行交互,特别是SQL数据库。本文将详细介绍如何在ASP.NET项目中连接SQL数据库,并提供最佳实践指南以确保开发过程的稳定性和效率。一、准备工作在开始之前,请确保您
52 3
|
11天前
|
SQL Java 数据库连接
如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
【10月更文挑战第6天】在代码与逻辑交织的世界中,我从一名数据库新手出发,通过不断探索与实践,最终成为熟练掌握JDBC的开发者。这段旅程充满挑战与惊喜,从建立数据库连接到执行SQL语句,再到理解事务管理和批处理等高级功能,每一步都让我对JDBC有了更深的认识。示例代码展示了如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
47 5
|
9天前
|
SQL 存储 Java
Java中使用ClickHouseDriver连接和基本操作
通过上述步骤,你可以轻松地在Java应用中集成ClickHouse数据库,执行基本的CRUD操作。需要注意的是,实际开发中应当根据实际情况调整数据库连接配置(如URL中的主机、端口、数据库名等),并根据应用需求选择合适的异常处理策略,确保代码的健壮性和资源的有效管理。此外,对于复杂查询和大批量数据处理,建议充分利用ClickHouse的特性(如分布式处理、列式存储优化等),以进一步提升性能。
9 2
|
9天前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
14 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
13天前
|
SQL 存储 数据可视化
SQL 数据库大揭秘:连接数字世界的魔法桥梁
在数字化时代,数据如繁星般璀璨,而 SQL 数据库则像强大的引力场,有序汇聚、整理和分析这些数据。SQL 数据库是一个巨大的数字宝库,装满各行各业的“宝藏”。本文将带你探索 SQL 数据库在电商、金融、医疗和教育等领域的应用。例如,在电商中,它能精准推荐商品;在金融中,它是安全卫士,防范欺诈;在医疗中,它是健康管家,管理病历;在教育中,则是智慧导师,个性化教学。此外,还将介绍如何利用板栗看板等工具实现数据可视化,提升决策效率。
|
14天前
|
SQL 开发框架 .NET
ASP连接SQL数据库:从基础到实践
随着互联网技术的快速发展,数据库与应用程序之间的连接成为了软件开发中的一项关键技术。ASP(ActiveServerPages)是一种在服务器端执行的脚本环境,它能够生成动态的网页内容。而SQL数据库则是一种关系型数据库管理系统,广泛应用于各类网站和应用程序的数据存储和管理。本文将详细介绍如何使用A
30 3
|
10天前
|
SQL 存储 监控
串口调试助手连接SQL数据库的技巧与方法
串口调试助手是电子工程师和软件开发人员常用的工具,它能够帮助用户进行串口通信的调试和数据分析
|
10天前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:实现过程与关键细节解析an3.021-6232.com
随着互联网技术的快速发展,ASP.NET作为一种广泛使用的服务器端开发技术,其与数据库的交互操作成为了应用开发中的重要环节。本文将详细介绍在ASP.NET中如何连接SQL数据库,包括连接的基本概念、实现步骤、关键代码示例以及常见问题的解决方案。由于篇幅限制,本文不能保证达到完整的2000字,但会确保
|
9天前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
43 6
|
7天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
38 3
Mysql(4)—数据库索引