想写博客已经很久了,今天终于空下来了。先从最近忙活了好几天的Java大作业开始吧,时间比较紧,主要讲思路和自己的一些体会,只贴了部分代码撒。
*PS:最近144刀拿下三年的阿里云服务器,为了更加深入了解前后端的知识,准备搭建个自己的网站,网站会陆续加一下奇奇怪怪的功能,希望各路带佬们多多支持(<ゝω・)☆
(1)用户:登录、注册、注销功能;查看所有车辆信息和已租用车辆总租金;租车、换车、退租功能。
(2)管理员:登录,注销功能;查看所有车辆信息、已被租用车辆及其租用用户和天数;修改包括价格在内的车辆信息,删除车辆信息(删除已被租用车辆时会进行提示);查看营业额。
(3)场景:用户暂时需要用车,在系统上租用一辆;新用户注册并进行租车操作;
(4)问题:选错车了,想换车怎么办?暂时不需要了,怎么办?想知道自己花了多少钱
(5)方案:选错车了可以换车;暂时不要了可以退租车辆;可以查看自己已租的车辆和总租金。
(<ゝω・)☆根据需求,用XMind画出系统功能结构图,查看总租金和退租功能综合考虑了用户的其他需求。想着用命令行界面和文件存储不太便于用户交互,就采用了Swing + MySQL完成该项目。
整体使用MySQL和Swing编程,方便用户交互和数据存取。RentSysMgr中有主函数,调用登录方法进入系统;UserClient和AdminClient为客户端,使用者进行相关操作;Register类中进行用户注册操作;管理员添加车辆和修改车辆信息功能单独分出两个类(因为租换退车辆需要调用到客户端的输入框变量,所以没有单独出来,而是采用在客户端中分情况编写)。Init方法用来初始化界面和功能,browseInfo方法用来在界面右端打印车辆详细信息,connectDB和closeDB方法用于连接和关闭MySQL。每个类都继承了Swing中的JFrame类和ActionLister接口,并重写接口中的actionPerformed方法实现主要功能。con变量用于连接和执行数据库,rs用于接收数据库操作结果,然后对数据进行处理并显示在界面上。
系统使用JDK1.8 + Idea + MySQL编写,数据库名为rental,连接root账户,密码242515。rental.sql直接导入root用户的数据库中即可。CarRental.jar为打包好的jar文件,可以通过cmd直接运行(在MySQL已启动且配置好的情况下)。其中,管理员账号密码为admin/admin;用户账号密码为user/user和test/123
public void connectDB() { // 连接数据库
try {
Class.forName("com.mysql.jdbc.Driver"); //通过反射注册驱动
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try { //JDBC创建连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/rental", "root", "242515");
} catch (SQLException e) {
e.printStackTrace();
}
}
public void closeDB() // 关闭连接
{
try {
state.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
package Main;
import Admin.AdminClient;
import User.Register;
import User.UserClient;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
public class Login extends JFrame implements ActionListener {
JTextField fieldOfAccount;
JPasswordField fieldOfPass;
JRadioButton userRadioButton, adminRadioButton;
JButton buttonOfLogin, buttonOfRegister;
Box box1, box2, box3, box4, boxField;//账号,密码,两个radiobutton,两个按钮都是用行式盒子布局。 basebox用列式把他们包裹起来。
Connection con = null;
Statement state = null;
ResultSet rs = null;
public Login() {
setLayout(new FlowLayout());
init();
setVisible(true);
setBounds(500, 200, 370, 280);
setTitle("C柚汽车租赁系统V4.0");
}
void init() {
box1 = Box.createHorizontalBox();
box1.add(new JLabel("账号:"));
box1.add(Box.createHorizontalStrut(8));
fieldOfAccount = new JTextField(20);
box1.add(fieldOfAccount); //登陆界面账号标签和输入框在同一行
box2 = Box.createHorizontalBox();
box2.add(new JLabel("密码:"));
box2.add(Box.createHorizontalStrut(8));
fieldOfPass = new JPasswordField(15);
box2.add(fieldOfPass);//登陆界面密码标签和输入框在同一行
box3 = Box.createHorizontalBox();
ButtonGroup group = new ButtonGroup();
userRadioButton = new JRadioButton("用户");
group.add(userRadioButton);
userRadioButton.addActionListener(this);
box3.add(userRadioButton);
box3.add(Box.createHorizontalStrut(8));
adminRadioButton = new JRadioButton("管理员");
group.add(adminRadioButton);
adminRadioButton.addActionListener(this);
box3.add(adminRadioButton); //登陆界面单选框
box4 = Box.createHorizontalBox();
buttonOfLogin = new JButton("登陆");
buttonOfLogin.addActionListener(this);
box4.add(buttonOfLogin);
box4.add(Box.createHorizontalStrut(8));
buttonOfRegister = new JButton("注册");
buttonOfRegister.addActionListener(this);
box4.add(buttonOfRegister); //登陆和注册两个按钮
boxField = Box.createVerticalBox();
boxField.add(Box.createVerticalStrut(40));
boxField.add(box1);
boxField.add(Box.createVerticalStrut(15));
boxField.add(box2);
boxField.add(Box.createVerticalStrut(23));
boxField.add(box3);
boxField.add(Box.createVerticalStrut(28));
boxField.add(box4); //把4个控件放进一个区域中
add(boxField);
}
public void connectDB() { // 连接数据库
try {
Class.forName("com.mysql.jdbc.Driver"); //通过反射注册驱动
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try { //JDBC创建连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/rental", "root", "242515");
} catch (SQLException e) {
e.printStackTrace();
}
}
public void closeDB() // 关闭连接
{
try {
state.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String userName = null;
String adminName = null;
String adminPass;
String userPass;
if (source == buttonOfLogin) { //如果点击的是登陆按钮,将判断单选框选择的是什么,做出相应的响应
if (!userRadioButton.isSelected() && !adminRadioButton.isSelected()) { //单选框没选择的错误处理
JOptionPane.showMessageDialog(null, "请选择身份!");
} else if (fieldOfAccount.getText().equals("") || fieldOfPass.getText().equals("")) { //判断是否输入了用户名和密码
JOptionPane.showMessageDialog(null, "登录名和密码不能为空!");
} else {
this.connectDB();
try {
state = con.createStatement();
} catch (SQLException e2) {
e2.printStackTrace();
}
if (adminRadioButton.isSelected())//如果选择的是管理员的按钮
{
try {
String sql = "select * from admin where adminName ='" + fieldOfAccount.getText() + "'";
rs = state.executeQuery(sql);
if (rs.next()) {
adminName = rs.getString(1);
adminPass = rs.getString(2);
if (!fieldOfPass.getText().equals(adminPass)) {
JOptionPane.showMessageDialog(null, "密码错误!");
fieldOfPass.setText("");
} else {
this.dispose();
new AdminClient(false);
}
} else {
JOptionPane.showMessageDialog(null, "此账号不是管理员账号!");
fieldOfAccount.setText("");
fieldOfPass.setText("");
}
} catch (HeadlessException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
} else //选择的是用户单选框
{
try {
String sql = "select * from user where userName ='" + fieldOfAccount.getText() + "'";
rs = state.executeQuery(sql);
if (rs.next()) {
userName = rs.getString(1);
userPass = rs.getString(2);
if (!fieldOfPass.getText().equals(userPass)) {
JOptionPane.showMessageDialog(null, "密码错误!");
fieldOfPass.setText("");
} else {
this.dispose();
new UserClient(fieldOfAccount.getText());
}
} else {
JOptionPane.showMessageDialog(null, "不存在此账号,请注册!");
fieldOfAccount.setText("");
fieldOfPass.setText("");
}
} catch (HeadlessException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
} else if (source == buttonOfRegister) {
this.dispose();
new Register();
}
}
}
package User;
import Main.Login;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
public class UserClient extends JFrame implements ActionListener {
//用户界面
JTable table;
JLabel label1;
Object data[][]; //存储表格数据的二维数组
Object column[] = {"编号", "车型", "车牌", "价格", "是否被租", "租用天数",}; //显示表格对应条目名称
JButton buttonOfUndo, buttonOfChange, buttonOfAble, buttonOfBrowse, buttonOfRent, buttonOfLogout, buttonOfRentCount, buttonOfMine;
Box boxLeft, boxRight;
JTextField fieldOfRent, fieldOfChange, fieldOfUndo;
JPanel jPanelLeft, jPanelRight;
Connection con = null;
Statement state = null;
ResultSet rs = null; //执行JDBC相关操作
String userName;
public UserClient(String userName) {
init();
setVisible(true);
setBounds(350, 200, 600, 510);
setTitle("欢迎使用C柚汽车租赁系统");
this.userName = userName;
}
void init() {
label1 = new JLabel(""); //空出一行让界面不那么紧凑
buttonOfAble = new JButton("可租用车辆");
buttonOfAble.addActionListener(this);
buttonOfBrowse = new JButton("车辆信息");
buttonOfBrowse.addActionListener(this);
buttonOfRent = new JButton(" 租 车 ");
buttonOfRent.addActionListener(this);
buttonOfChange = new JButton(" 换 车 ");
buttonOfChange.addActionListener(this);
buttonOfUndo = new JButton(" 退 租 ");
buttonOfUndo.addActionListener(this);
buttonOfMine = new JButton(" 我租的车 ");
buttonOfMine.addActionListener(this);
buttonOfRentCount = new JButton(" 总租金 ");
buttonOfRentCount.addActionListener(this);
buttonOfLogout = new JButton(" 退出登录 ");
buttonOfLogout.addActionListener(this);
// label2 = new JLabel("输入要租用车辆的编号:");
// label3 = new JLabel("输入要替换车辆的编号:");
fieldOfRent = new JTextField("要租车辆的编号");
fieldOfChange = new JTextField("原来车辆的编号");
fieldOfUndo = new JTextField("退租车辆的编号");
fieldOfRent.setHorizontalAlignment(JTextField.CENTER);
fieldOfChange.setHorizontalAlignment(JTextField.CENTER);
fieldOfUndo.setHorizontalAlignment(JTextField.CENTER); //设置输入框对齐方式为居中
data = new Object[50][6];
table = new JTable(data, column);//组件的创建
table.setEnabled(false);
JScrollPane scrollPane = new JScrollPane(table);
buttonOfBrowse.setPreferredSize(new Dimension(36, 27));
buttonOfRentCount.setPreferredSize(new Dimension(36, 27));
buttonOfMine.setPreferredSize(new Dimension(36, 27));
buttonOfRent.setPreferredSize(new Dimension(36, 27));
buttonOfAble.setPreferredSize(new Dimension(36, 27));
buttonOfLogout.setPreferredSize(new Dimension(36, 27));
buttonOfChange.setPreferredSize(new Dimension(36, 27));
buttonOfUndo.setPreferredSize(new Dimension(36, 27)); //统一按钮样式
boxLeft = Box.createVerticalBox();
boxLeft.add(Box.createVerticalStrut(25));
boxLeft.add(buttonOfAble);
boxLeft.add(Box.createVerticalStrut(10));
boxLeft.add(buttonOfBrowse);
boxLeft.add(Box.createVerticalStrut(28));
boxLeft.add(fieldOfRent);
boxLeft.add(Box.createVerticalStrut(5));
boxLeft.add(buttonOfRent);
boxLeft.add(Box.createVerticalStrut(15));
boxLeft.add(fieldOfChange);
boxLeft.add(Box.createVerticalStrut(5));
boxLeft.add(buttonOfChange);
boxLeft.add(Box.createVerticalStrut(15));
boxLeft.add(fieldOfUndo);
boxLeft.add(Box.createVerticalStrut(5));
boxLeft.add(buttonOfUndo);
boxLeft.add(Box.createVerticalStrut(27));
boxLeft.add(buttonOfMine);
boxLeft.add(Box.createVerticalStrut(12));
boxLeft.add(buttonOfRentCount);
boxLeft.add(Box.createVerticalStrut(12));
boxLeft.add(buttonOfLogout);
boxRight = Box.createHorizontalBox();
boxRight.add(Box.createHorizontalStrut(5));
boxRight.add(boxLeft); //左边的按钮部分用 box布局
jPanelLeft = new JPanel();
jPanelRight = new JPanel();
jPanelLeft.setLayout(new BorderLayout());
jPanelLeft.add(boxRight, BorderLayout.NORTH);//把左边的按钮部分放到jPanelLeft中。
jPanelRight.setLayout(new BorderLayout());
jPanelRight.add(label1, BorderLayout.NORTH);
jPanelRight.add(scrollPane, BorderLayout.CENTER);//把表格 放JPanelRight里
this.setLayout(new BorderLayout());
add(jPanelRight, BorderLayout.EAST);
add(jPanelLeft, BorderLayout.WEST);//把两个大的Panel放到窗口里面
}
public void browseInfo() {
int i = 0;
while (i < 50) {
data[i][0] = " ";
data[i][1] = " ";
data[i][2] = " ";
data[i][3] = " ";
data[i][4] = " ";
data[i][5] = " ";
i++;
}
i = 0;
this.connectDB();
try {
state = con.createStatement();
String sql = "select * from car_info";
rs = state.executeQuery(sql);
while (rs.next()) {
String ID = rs.getString("ID");
String carType = rs.getString("carType");
String license = rs.getString("license ");
String price = rs.getString("price");
String days = rs.getString("days");
String isHire = rs.getString("isHire");
data[i][0] = ID;
data[i][1] = carType;
data[i][2] = license;
data[i][3] = price;
data[i][4] = days;
data[i][5] = isHire;
i++;
}
this.closeDB();
repaint();
} catch (SQLException e1) {
e1.printStackTrace();
}
this.closeDB();
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == buttonOfAble) //可租用车辆按钮
{
int flag = 0; //用来判断有没有没被租用的车辆,如果能返回 “否” 值(未被租用车辆)的集,则赋值为 1
int i = 0;
while (i < 50) {
data[i][0] = " ";
data[i][1] = " ";
data[i][2] = " ";
data[i][3] = " ";
data[i][4] = " ";
data[i][5] = " ";
i++;
}
i = 0; //i 赋值为0, 为下面的循环做准备
this.connectDB();
try {
state = con.createStatement();
String sql = "select * from car_info where isHire= '否';";//查询表里面 没被租用的车辆
rs = state.executeQuery(sql);
while (rs.next()) //把查询到的信息写入右边的表格中
{
String ID = rs.getString("ID");
String carType = rs.getString("carType");
String license = rs.getString("license");
String price = rs.getString("price");
String days = rs.getString("days");
String isHire = rs.getString("isHire");
data[i][0] = ID;
data[i][1] = carType;
data[i][2] = license;
data[i][3] = price;
data[i][4] = isHire;
data[i][5] = days;
i++;
flag = 1;
}
this.closeDB();
repaint();//刷新一下
} catch (SQLException e1) {
e1.printStackTrace();
}
if (flag == 0) {
JOptionPane.showMessageDialog(null, "车辆都已被租用!");
}
} else if (source == buttonOfBrowse)//点击信息浏览按钮
{
int i = 0;
while (i < 50) {
data[i][0] = " ";
data[i][1] = " ";
data[i][2] = " ";
data[i][3] = " ";
data[i][4] = " ";
data[i][5] = " ";
i++;
}
i = 0;
this.connectDB();
try {
state = con.createStatement();
String sql = "select * from car_info";
rs = state.executeQuery(sql);
while (rs.next()) {
String ID = rs.getString("ID");
String carType = rs.getString("carType");
String license = rs.getString("license");
String price = rs.getString("price");
String days = rs.getString("days");
String isHire = rs.getString("isHire");
data[i][0] = ID;
data[i][1] = carType;
data[i][2] = license;
data[i][3] = price;
data[i][4] = isHire;
data[i][5] = days;
i++;
}
this.closeDB();
repaint();
} catch (SQLException e1) {
e1.printStackTrace();
}
} else if (source == buttonOfRent) { //租车按钮
if (fieldOfRent.getText().equals("")) //判断输入是否为空
{
JOptionPane.showMessageDialog(null, "请输入租用车辆的编号!");
} else {
this.connectDB();
String sql;
try {
state = con.createStatement();
sql = "select * from car_info where ID='" + fieldOfRent.getText() + "' and isHire = '否'";//获取输入的编号并且没被租用车辆的信息
rs = state.executeQuery(sql);
} catch (SQLException e2) {
e2.printStackTrace();
}
try {
if (rs.next()) //判断要租编号的车辆是否存在并且未被租用
{
int userRentDay = Integer.parseInt(JOptionPane.showInputDialog("请输入租用天数:"));
int money = userRentDay * Integer.parseInt(rs.getString("price"));
this.connectDB();
int n = JOptionPane.showConfirmDialog(this, "你总共需要支付" + money + "元", "支付对话框(模拟)", JOptionPane.YES_NO_OPTION);
if (n == JOptionPane.YES_OPTION) //确认框
{
try {
state = con.createStatement();
String sql1 = "UPDATE `car_info` SET `money`='" + money + "' WHERE `ID`=" + fieldOfRent.getText() + ";";
state.executeUpdate(sql1);
String sql2 = "UPDATE `car_info` SET `days`='" + userRentDay + "' WHERE `ID`=" + fieldOfRent.getText() + ";";
state.executeUpdate(sql2);
String sql3 = "update car_info set isHire = '是',userName = '" + userName + "' where ID='" + fieldOfRent.getText() + "';";//把租用的赋值为 是
state.executeUpdate(sql3);
} catch (SQLException e1) {
e1.printStackTrace();
}
this.closeDB();
repaint();
fieldOfRent.setText(""); //输入框置空
JOptionPane.showMessageDialog(null, "租用成功!");
browseInfo();
}
} else {
JOptionPane.showMessageDialog(null, "无法租用此车辆,请重新输入!");
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
} else if (source == buttonOfChange) {
if (fieldOfChange.getText().equals("")) { //是否为空
JOptionPane.showMessageDialog(null, "请输入要换车的编号!");
} else {
this.connectDB();
String sql;
try {
state = con.createStatement();
sql = "select * from car_info where ID='" + fieldOfChange.getText() + "' and isHire = '是' and userName = '" + userName + "'; ";//获取输入的 编号并且 被租用的信息
rs = state.executeQuery(sql);
if (rs.next()) //判断是否可以更换,即需要更换的车辆是否被其他人租用
{
int currentID = Integer.parseInt(JOptionPane.showInputDialog("请输入租用新车的编号:"));
String sql5 = "select * from car_info where ID='" + currentID + "'and isHire = '否' "; //获取输入的新编号并且未租用的信息
rs = state.executeQuery(sql5);
if (rs.next()) {
int userRentDay1 = Integer.parseInt(JOptionPane.showInputDialog("请输入租用新车的天数:"));
int money1 = userRentDay1 * Integer.parseInt(rs.getString("price"));
int n = JOptionPane.showConfirmDialog(this, "你总共需要支付" + money1 + "元", "", JOptionPane.YES_NO_OPTION);
if (n == JOptionPane.YES_OPTION) //确认框
{
try {
this.connectDB();
state = con.createStatement();
String sql0 = "update car_info set isHire = '否',userName = '' where ID='" + fieldOfChange.getText() + "';";
state.executeUpdate(sql0); //先把被替换车辆的租用情况置为否
String sql1 = "UPDATE `car_info` SET `money`='" + money1 + "' WHERE `ID`=" + currentID + ";";
state.executeUpdate(sql1);
String sql2 = "UPDATE `car_info` SET `days`='" + userRentDay1 + "' WHERE `ID`=" + currentID + ";";
state.executeUpdate(sql2);
String sql3 = "update car_info set isHire = '是',userName = '" + userName + "' where ID='" + currentID + "';";//把租用的赋值为 是
state.executeUpdate(sql3); //进行换车操作
} catch (SQLException e1) {
e1.printStackTrace();
}
this.closeDB();
repaint();
fieldOfChange.setText(""); //输入框置空
JOptionPane.showMessageDialog(null, "租用成功!");
browseInfo();
}
} else {
JOptionPane.showMessageDialog(null, "输入错误,无法替换,请重新输入");
}
}
} catch (SQLException e2) {
e2.printStackTrace();
}
}
} else if (source == buttonOfUndo) {
if (fieldOfUndo.getText().equals("")) //是否为空
{
JOptionPane.showMessageDialog(null, "请输入要退租的编号!");
} else //不为空
{
this.connectDB();
String sql;
try {
state = con.createStatement();
sql = "select * from car_info where ID='" + fieldOfUndo.getText() + "' and isHire = '是' ; ";//获取输入的 编号并且 被租用的信息
rs = state.executeQuery(sql);
if (rs.next()) //判断是否可以退租,即需要退租的车辆是否被当前用户租用
{
int n = JOptionPane.showConfirmDialog(this, "确定要退租吗?", "确认退租界面", JOptionPane.YES_NO_OPTION);
if (n == JOptionPane.YES_OPTION) //确认框
{
try {
this.connectDB();
state = con.createStatement();
sql = "update car_info set isHire = '否',userName = '', money = 0, days = 0 where ID='" + fieldOfUndo.getText() + "';";
state.executeUpdate(sql);
} catch (SQLException e1) {
e1.printStackTrace();
}
this.closeDB();
repaint();
fieldOfUndo.setText(""); //输入框置空
JOptionPane.showMessageDialog(null, "退租成功!");
browseInfo();
}
} else {
JOptionPane.showMessageDialog(null, "输入错误,无法退租,请重新输入");
}
} catch (SQLException e2) {
e2.printStackTrace();
}
}
} else if (source == buttonOfRentCount) {
this.connectDB();
try {
state = con.createStatement();
String sql = "select money from car_info where userName='" + this.userName + "'; ";
rs = state.executeQuery(sql);
} catch (SQLException e2) {
e2.printStackTrace();
}
try {
int totalRent = 0;
while (rs.next()) {
totalRent += rs.getInt("money");
} //遍历计算总租金
JOptionPane.showMessageDialog(null, "您总共花费了" + totalRent + "元用于租车");
} catch (HeadlessException e2) {
e2.printStackTrace();
} catch (SQLException e2) {
e2.printStackTrace();
}
} else if (source == buttonOfLogout) {
this.dispose();
new Login();
} else if (source == buttonOfMine)//点击我租的车辆信息
{
int flag = 0; //用来判断该用户有无租用车辆
int i = 0;
while (i < 50) {
data[i][0] = " ";
data[i][1] = " ";
data[i][2] = " ";
data[i][3] = " ";
data[i][4] = " ";
data[i][5] = " ";
i++;
}
i = 0;//i 赋值为 0,为下面的循环做准备
this.connectDB();
try {
state = con.createStatement();
String sql = "select * from car_info where userName= '" + userName + "';";//查询表里面 自己已经租用的车辆
rs = state.executeQuery(sql);
while (rs.next()) //把查询到的信息写入右边的表格中
{
String ID = rs.getString("ID");
String carType = rs.getString("carType");
String license = rs.getString("license");
String price = rs.getString("price");
String days = rs.getString("days");
String isHire = rs.getString("isHire");
data[i][0] = ID;
data[i][1] = carType;
data[i][2] = license;
data[i][3] = price;
data[i][4] = isHire;
data[i][5] = days;
i++;
flag = 1;
}
this.closeDB();
repaint();//刷新一下
} catch (SQLException e1) {
e1.printStackTrace();
}
if (flag == 0) {
JOptionPane.showMessageDialog(null, "您还没有租用任何车辆!");
}
}
}
public void connectDB() { // 连接数据库
try {
Class.forName("com.mysql.jdbc.Driver"); //通过反射注册驱动
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try { //JDBC创建连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/rental?characterEncoding=utf-8", "root", "242515");
} catch (SQLException e) {
e.printStackTrace();
}
}
public void closeDB() // 关闭连接
{
try {
state.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
之前三个版本的系统都是基于命令行的,不便于用户交互。所以打算尝试最后一节Java课教的Swing组件+美化主题来完成大作业。晚上找了Swing的教程自学了下,采用MySQL + JDBC+反射进行数据操作(之前学过SQL注入,所以有一定基础)。主要框架借鉴了房屋租赁系统,并根据车辆不同的属性进行调整优化。在这过程中遇到了不少问题,也发现了自己基础并不是很扎实,还需要注意不少细节。例如总营业额的计算,需要将select money from car_info得到的结果进行提取遍历然后累加才能计算出营业额,用户端总租金计算也是相同道理。还有换车功能的实现需要考虑很多不同的因素,进行相应的错误处理,输入别人租用的车和未被租用去换车都需要进行提示,
Swing组件使用时,我深深体会到了面向对象的优势,采用工厂模式重写ActionListener接口让相应功能更好实现,继承JFrame类来减少代码量和提高运行速度;异常处理是一个很考验程序员功底的事,要能想到用户的痛点,找到最好的解决方案,在几天的程序编写中,我遇到了不少SQL方面的异常,相信这对我以后学习数据库和今后的项目开发都会有很大的帮助。
通过这次实验,我认识到了自身编程习惯的问题,也意识到有问题去问有项目经验的人能更好地解决,也能学到更多东西。
十一月份打算尝试做出租车5.0, 6.0,添加更多功能,学更多知识,积累更多经验,为以后工作做准备(如果可以,打算做一个网页端来实现前后端结合的租赁系统)。