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

简介: 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;
目录
相关文章
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
11月前
|
SQL Java 关系型数据库
Java连接MySQL数据库环境设置指南
请注意,在实际部署时应该避免将敏感信息(如用户名和密码)硬编码在源码文件里面;应该使用配置文件或者环境变量等更为安全可靠地方式管理这些信息。此外,在处理大量数据时考虑使用PreparedStatement而不是Statement可以提高性能并防止SQL注入攻击;同时也要注意正确处理异常情况,并且确保所有打开过得资源都被正确关闭释放掉以防止内存泄漏等问题发生。
494 13
|
11月前
|
SQL 关系型数据库 MySQL
MySQL数据库连接过多(Too many connections)错误处理策略
综上所述,“Too many connections”错误处理策略涉及从具体参数配置到代码层面再到系统与架构设计全方位考量与改进。每项措施都需根据具体环境进行定制化调整,并且在执行任何变更前建议先行测试评估可能带来影响。
1880 11
|
人工智能 Java 关系型数据库
Java的时间处理与Mysql的时间查询
本文总结了Java中时间与日历的常用操作,包括时间的转换、格式化、日期加减及比较,并介绍了MySQL中按天、周、月、季度和年进行时间范围查询的方法,适用于日常开发中的时间处理需求。
249 0
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
830 0
|
SQL 数据库连接 数据库
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
921 14
|
11月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
636 158
|
11月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。

推荐镜像

更多