基于数据库的收支管理系统
// 收入支出记录类
class Record {
private int id; // 记录的唯一标识符
private String category; // 记录的分类(如餐饮、娱乐等)
private String type; // 记录的类型(如收入或支出)
private double amount; // 记录的金额
private String date; // 记录的日期
// 构造函数,用于创建新的记录对象
public Record(int id, String category, String type, double amount, String date) {
this.id = id; // 设置记录的ID
this.category = category; // 设置记录的分类
this.type = type; // 设置记录的类型
this.amount = amount; // 设置记录的金额
this.date = date; // 设置记录的日期
}
// 获取记录的ID
public int getId() {
return id;
}
// 获取记录的分类
public String getCategory() {
return category;
}
// 获取记录的类型
public String getType() {
return type;
}
// 获取记录的金额
public double getAmount() {
return amount;
}
// 获取记录的日期
public String getDate() {
return date;
}
}
// 收入支出记录管理类
class RecordManager {
private Connection connection; // 数据库连接对象
// 构造函数,用于创建新的记录管理对象
public RecordManager(Connection connection) {
this.connection = connection; // 设置数据库连接
}
// 添加新的记录
public void addRecord(String category, String type, double amount, String date) {
try {
// 准备SQL语句,插入新记录
PreparedStatement statement = connection.prepareStatement("INSERT INTO records (category, type, amount, date) VALUES (?, ?, ?, now())");
statement.setString(1, category); // 设置第一个参数:分类
statement.setString(2, type); // 设置第二个参数:类型
statement.setDouble(3, amount); // 设置第三个参数:金额
//在这里不设置日期直接使用当前时间信息作为日期
statement.executeUpdate(); // 执行SQL语句
//成功提示成功信息
System.out.println("记录添加成功!");
} catch (SQLException e) {
//如果失败提示错误
System.out.println("记录添加失败:" + e.getMessage()); // 打印错误信息
}
}
// 编辑已存在的记录
public void editRecord(int id, String category, String type, double amount, String date) {
try {
// 准备SQL语句,更新记录
PreparedStatement statement = connection.prepareStatement("UPDATE records SET category=?, type=?, amount=? WHERE id=?");
statement.setString(1, category); // 设置第一个参数:分类
statement.setString(2, type); // 设置第二个参数:类型
statement.setDouble(3, amount); // 设置第三个参数:金额
statement.setInt(4, id); // 设置第四个参数:ID
statement.executeUpdate(); // 执行SQL语句
System.out.println("记录修改成功!");
} catch (SQLException e) {
//如果失败提示错误
System.out.println("记录修改失败:" + e.getMessage()); // 打印错误信息
}
}
// 删除已存在的记录
public void deleteRecord(int id) {
try {
// 准备SQL语句,删除记录
PreparedStatement statement = connection.prepareStatement("DELETE FROM records WHERE id=?");
statement.setInt(1, id); // 设置第一个参数:ID
statement.executeUpdate(); // 执行SQL语句
System.out.println("记录删除成功!");
} catch (SQLException e) {
System.out.println("记录删除失败:" + e.getMessage()); // 打印错误信息
}
}
// 获取所有记录
public List<Record> getRecords() {
List<Record> records = new ArrayList<>(); // 创建用于存储记录的列表
try {
// 准备SQL语句,查询所有记录
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM records");
while (resultSet.next()) {
// 获取查询结果中的每一行,并创建对应的记录对象
int id = resultSet.getInt("id");
String category = resultSet.getString("category");
String type = resultSet.getString("type");
double amount = resultSet.getDouble("amount");
String date = resultSet.getString("date");
records.add(new Record(id, category, type, amount, date)); // 将新建的记录对象添加到列表中
}
} catch (SQLException e) {
System.out.println("获取记录失败:" + e.getMessage()); // 打印错误信息
}
return records; // 返回包含所有记录的列表
}
}
// 收入支出统计类
class StatisticsManager {
private Connection connection;
public StatisticsManager(Connection connection) {
this.connection = connection;
}
public void showCategoryStatistics() {
try {
// 首先查询出总金额
Statement totalAmountStatement = connection.createStatement();
ResultSet totalAmountResultSet = totalAmountStatement.executeQuery("SELECT SUM(amount) AS total_amount FROM records");
totalAmountResultSet.next();
double totalAmount = totalAmountResultSet.getDouble("total_amount");
// 查询每个类别的总金额,并计算其占总金额的比例
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT category, SUM(amount) AS category_amount FROM records GROUP BY category");
while (resultSet.next()) {
String category = resultSet.getString("category");
double categoryAmount = resultSet.getDouble("category_amount");
double categoryPercentage = (categoryAmount / totalAmount) * 100; // 计算百分比
System.out.printf("%s: %.2f (%.2f%%)\n", category, categoryAmount, categoryPercentage); // 打印类别、金额和百分比
}
} catch (SQLException e) {
System.out.println("获取统计信息失败:" + e.getMessage());
}
}
}
// 预算管理类
class BudgetManager {
private Connection connection; // 数据库连接对象
private double budget; // 预算金额
// 构造函数,用于创建新的预算管理对象
public BudgetManager(Connection connection, double budget) {
this.connection = connection; // 设置数据库连接
this.budget = budget; // 设置预算金额
}
// 检查预算
public void checkBudget() {
try {
// 准备SQL语句,按类型统计总金额
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT type, SUM(amount) AS total_amount FROM records GROUP BY type");
double totalExpense = 0.0; // 总支出
double totalIncome = 0.0; // 总收入
while (resultSet.next()) {
// 计算总支出和总收入
String type = resultSet.getString("type");
double totalAmount = resultSet.getDouble("total_amount");
if (type.equals("支出")) {
totalExpense = totalAmount;
} else if (type.equals("收入")) {
totalIncome = totalAmount;
}
}
// 计算预算情况,并打印信息
//如果总支出大于总收入+预算金额超出预算
double balance = budget + totalIncome;
System.out.println("总支出"+totalExpense);
System.out.println("剩余预算"+balance);
//如果总余额大于预算 提示超出预算
if (balance < totalExpense) {
System.out.println("超出预算!");
//否则提示预算良好
} else {
System.out.println("预算情况良好!");
}
} catch (SQLException e) {
System.out.println("检查预算失败:" + e.getMessage()); // 打印错误信息
}
}
}
// 主程序类
class PersonalAccountBook {
public static void main(String[] args) {
try {
// 连接数据库设置数据库名密码
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/income_expense", "root", "123456");
RecordManager recordManager = new RecordManager(connection); // 创建记录管理对象
StatisticsManager statisticsManager = new StatisticsManager(connection); // 创建统计管理对象
BudgetManager budgetManager = new BudgetManager(connection, 10000.0); // 创建预算管理对象
Scanner scanner = new Scanner(System.in); // 创建用于获取用户输入的Scanner对象
int choice = -1; // 用户的选择
while (choice != 0) {
System.out.println("*************收支记录系统****************");
// 打印菜单,并获取用户的选择
System.out.println("\t\t\t1. 添加记录");
System.out.println("\t\t\t2. 修改记录");
System.out.println("\t\t\t3. 删除记录");
System.out.println("\t\t\t4. 查询记录");
System.out.println("\t\t\t5. 显示分类统计");
System.out.println("\t\t\t6. 检查预算");
System.out.println("\t\t\t0. 退出");
System.out.println("****************************************");
System.out.print("请输入选项:");
choice = scanner.nextInt();
scanner.nextLine();
// 根据用户的选择,执行相应的操作
switch (choice) {
case 1: // 添加记录
System.out.print("请输入类别(如餐饮、娱乐):");
String category = scanner.nextLine();
String type = "";
while (true) {
System.out.print("请输入类型(收入、支出):");
type = scanner.nextLine();
if (type.equals("收入") || type.equals("支出")) {
break;
}
System.out.println("请按格式输入");
}
System.out.print("请输入金额:");
double amount = scanner.nextDouble();
scanner.nextLine();
//键盘输入信息 调用add的方法将信息传递过去
//在这里不添加日期信息,直接只用系统当前日期
recordManager.addRecord(category, type, amount, null);
break;
case 2: // 修改记录
//键盘输入信息 调用修改方法 传递参数
System.out.print("请输入要修改的记录ID:");
int id = scanner.nextInt();
scanner.nextLine();
System.out.print("请输入类别(如餐饮、娱乐):");
category = scanner.nextLine();
while (true) {
System.out.print("请输入类型(收入、支出):");
type = scanner.nextLine();
if (type.equals("收入") || type.equals("支出")) {
break;
}
System.out.println("请按格式输入");
}
System.out.print("请输入金额:");
amount = scanner.nextDouble();
scanner.nextLine();
recordManager.editRecord(id, category, type, amount, null);
break;
case 3: // 删除记录
System.out.print("请输入要删除的记录ID:");
id = scanner.nextInt();
scanner.nextLine();
recordManager.deleteRecord(id);
break;
case 4: // 查询记录
List<Record> records = recordManager.getRecords();
if (records == null) {
System.out.println("暂时还没有收入支出的相关信息");
break;
}
for (Record record : records) {
System.out.println(record.getId() + " " + record.getCategory() + " " + record.getType() + " " + record.getAmount() + " " + record.getDate());
}
break;
case 5: // 显示分类统计
statisticsManager.showCategoryStatistics();
break;
case 6: // 检查预算
budgetManager.checkBudget();
break;
case 0: // 退出
System.out.println("谢谢使用,再见!");
break;
default:
System.out.println("无效的选项,请重新输入!");
break;
}
}
scanner.close(); // 关闭Scanner对象
connection.close(); // 关闭数据库连接
} catch (SQLException e) {
System.out.println("数据库操作失败:" + e.getMessage()); // 打印错误信息
}
}
}
数据库文件
在对应数据库下直接右键执行即可
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for records
-- ----------------------------
DROP TABLE IF EXISTS `records`;
CREATE TABLE `records` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`category` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`amount` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`date` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of records
-- ----------------------------
INSERT INTO `records` VALUES (5, '娱乐', '支出', '500.0', '2023-06-16 15:28:23');
INSERT INTO `records` VALUES (6, '存款', '收入', '10000.0', '2023-06-16 15:29:23');
INSERT INTO `records` VALUES (7, '餐饮', '支出', '300.0', '2023-06-16 15:29:44');
INSERT INTO `records` VALUES (8, '旅行', '支出', '2000.0', '2023-06-16 15:34:49');
INSERT INTO `records` VALUES (9, '电玩', '支出', '150.0', '2023-06-16 15:38:15');
SET FOREIGN_KEY_CHECKS = 1;
###运行截图