C++实现对数据库和表的基本操作

###课设要求
问题描述:设计一个Database类。Database类是一个表的集合,而表又由行和列组成。例如,下面的雇员信息表包含三个记录,每个记录有四个字段(Employee、Name、Department和Boss)。

雇员姓名部门部门经理
111-11-1234CruzACCWarder
213-44-5649JohnstonMISMichaels
321-88-7895TomFINBearskin
  1. 基本要求:能够完成对数据库的基本操作;包括创建数据库,实现对数据库里面的表的添加,删除;以及能够完成对表结构的修改(如添加或删除字段),以及对表中的记录进行添加和删除;能够完成对使用适当的查询语言从一个或多个表中查找相关信息。
  2. 测试数据:可以选取高校人员(教师、学生、职工等)数据库作为测试数据
  3. 实现提示:
    Database 类的公有接口包含如下数据成员:
  • 创建一个表。
  • 通过增加或删除字段修改表结构。
  • 删除一个表。
  • 在表中增加一个记录。
  • 从表中删除记录。
  • 用适当的查询语言从一个或多个表中查找信息。

选做内容:高校人员信息通常保存在文件里面,可以从文件里面读取人员信息;然后完成上面操作

大纲

包含的头文件

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <fstream>
#include <sstream>

定义记录和表

定义一个记录类表示表中的一行,表类表示数据库中的表。

class Record 
{
public:
    std::unordered_map<std::string, std::string> fields;

    void setField(const std::string& fieldName, const std::string& value) 
    {
        fields[fieldName] = value;
    }

    std::string getField(const std::string& fieldName) const 
    {
        auto it = fields.find(fieldName);
        if (it != fields.end()) 
        {
            return it->second;
        } else 
        {
            return "";
        }
    }
};

class Table 
{
public:
    std::vector<std::string> columnNames;
    std::vector<Record> records;

    void addColumn(const std::string& columnName) 
    {
        columnNames.push_back(columnName);
    }

    void removeColumn(const std::string& columnName) 
    {
        columnNames.erase(std::remove(columnNames.begin(), columnNames.end(), columnName), columnNames.end());
        for (auto& record : records) 
        {
            record.fields.erase(columnName);
        }
    }

    void addRecord(const Record& record) 
    {
        records.push_back(record);
    }

    void deleteRecord(int index) 
    {
        if (index >= 0 && index < records.size()) 
        {
            records.erase(records.begin() + index);
        }
    }

    Record* getRecord(int index) 
    {
        if (index >= 0 && index < records.size()) 
        {
            return &records[index];
        } else 
        {
            return nullptr;
        }
    }
};

数据库类

定义一个Database类来管理多个表。

class Database {
private:
    std::unordered_map<std::string, Table> tables;

public:
    void createTable(const std::string& tableName, const std::vector<std::string>& columns) 
    {
        Table newTable;
        for (const auto& column : columns) 
        {
            newTable.addColumn(column);
        }
        tables[tableName] = newTable;
    }

    void deleteTable(const std::string& tableName) 
    {
        tables.erase(tableName);
    }

    Table* getTable(const std::string& tableName) 
    {
        auto it = tables.find(tableName);
        if (it != tables.end()) 
        {
            return &(it->second);
        } else 
        {
            return nullptr;
        }
    }

    void addRecordToTable(const std::string& tableName, const Record& record) 
    {
        auto table = getTable(tableName);
        if (table) 
        {
            table->addRecord(record);
        }
    }

    void deleteRecordFromTable(const std::string& tableName, int index) 
    {
        auto table = getTable(tableName);
        if (table) 
        {
            table->deleteRecord(index);
        }
    }

    std::vector<Record> queryTable(const std::string& tableName, const std::string& columnName, const std::string& value) 
    {
        std::vector<Record> results;
        auto table = getTable(tableName);
        if (table) 
        {
            for (const auto& record : table->records) 
            {
                if (record.getField(columnName) == value) 
                {
                    results.push_back(record);
                }
            }
        }
        return results;
    }

    void loadFromFile(const std::string& tableName, const std::string& filePath) 
    {
        std::ifstream file(filePath);
        if (!file.is_open()) 
        {
            std::cerr << "Error opening file: " << filePath << std::endl;
            return;
        }

        std::string line;
        if (std::getline(file, line)) 
        {
            std::istringstream iss(line);
            std::vector<std::string> columns;
            std::string column;
            while (std::getline(iss, column, ',')) 
            {
                columns.push_back(column);
            }
            createTable(tableName, columns);
        }

        Table* table = getTable(tableName);
        if (!table)
        {
        	return;
        }

        while (std::getline(file, line)) 
        {
            std::istringstream iss(line);
            std::string value;
            Record record;
            int colIndex = 0;
            while (std::getline(iss, value, ',')) 
            {
                if (colIndex < table->columnNames.size()) 
                {
                    record.setField(table->columnNames[colIndex], value);
                    colIndex++;
                }
            }
            table->addRecord(record);
        }
        file.close();
    }
};

测试代码

int main() 
{
    Database db;
    db.loadFromFile("employee", "employee_data.txt");

    db.createTable("students", {"ID", "Name", "Major"});
    Record student;
    student.setField("ID", "12345");
    student.setField("Name", "Alice");
    student.setField("Major", "Computer Science");
    db.addRecordToTable("students", student);

    auto results = db.queryTable("students", "Major", "Computer Science");
    for (const auto& record : results) 
    {
        std::cout << "ID: " << record.getField("ID") << ", Name: " << record.getField("Name") << std::endl;
    }

    db.deleteRecordFromTable("students", 0);
    db.deleteTable("students");

    return 0;
}

解释

  1. Record类:用unordered_map存储字段名和值,提供方法来设置和获取字段值。
  2. Table类:存储列名和记录,提供方法来添加和删除列、添加和删除记录。
  3. Database类:管理多个表,提供创建和删除表、添加和删除记录、查询表的方法。
  4. 文件读取功能:通过loadFromFile方法,从文件读取数据并创建相应的表和记录。
  5. 测试代码:展示如何使用Database类来完成创建表、添加记录、查询记录、删除记录和表的操作。

完整代码

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <fstream>
#include <sstream>
#include <algorithm>

class Record 
{
public:
    std::unordered_map<std::string, std::string> fields;

    void setField(const std::string& fieldName, const std::string& value) 
    {
        fields[fieldName] = value;
    }

    std::string getField(const std::string& fieldName) const 
    {
        auto it = fields.find(fieldName);
        if (it != fields.end()) 
        {
            return it->second;
        } else 
        {
            return "";
        }
    }
};

class Table 
{
public:
    std::vector<std::string> columnNames;
    std::vector<Record> records;

    void addColumn(const std::string& columnName) 
    {
        columnNames.push_back(columnName);
    }

    void removeColumn(const std::string& columnName) 
    {
        columnNames.erase(std::remove(columnNames.begin(), columnNames.end(), columnName), columnNames.end());
        for (auto& record : records) 
        {
            record.fields.erase(columnName);
        }
    }

    void addRecord(const Record& record) 
    {
        records.push_back(record);
    }

    void deleteRecord(int index) 
    {
        if (index >= 0 && index < records.size()) 
        {
            records.erase(records.begin() + index);
        }
    }

    Record* getRecord(int index) 
    {
        if (index >= 0 && index < records.size()) 
        {
            return &records[index];
        } else 
        {
            return nullptr;
        }
    }
};

class Database 
{
private:
    std::unordered_map<std::string, Table> tables;

public:
    void createTable(const std::string& tableName, const std::vector<std::string>& columns) 
    {
        Table newTable;
        for (const auto& column : columns) 
        {
            newTable.addColumn(column);
        }
        tables[tableName] = newTable;
    }

    void deleteTable(const std::string& tableName) 
    {
        tables.erase(tableName);
    }

    Table* getTable(const std::string& tableName) 
    {
        auto it = tables.find(tableName);
        if (it != tables.end()) 
        {
            return &(it->second);
        } else 
        {
            return nullptr;
        }
    }

    void addRecordToTable(const std::string& tableName, const Record& record) 
    {
        auto table = getTable(tableName);
        if (table) 
        {
            table->addRecord(record);
        }
    }

    void deleteRecordFromTable(const std::string& tableName, int index) 
    {
        auto table = getTable(tableName);
        if (table) 
        {
            table->deleteRecord(index);
        }
    }

    std::vector<Record> queryTable(const std::string& tableName, const std::string& columnName, const std::string& value) 
    {
        std::vector<Record> results;
        auto table = getTable(tableName);
        if (table) 
        {
            for (const auto& record : table->records) 
            {
                if (record.getField(columnName) == value) 
                {
                    results.push_back(record);
                }
            }
        }
        return results;
    }

    void loadFromFile(const std::string& tableName, const std::string& filePath) 
    {
        std::ifstream file(filePath);
        if (!file.is_open()) 
        {
            std::cerr << "Error opening file: " << filePath << std::endl;
            return;
        }

        std::string line;
        if (std::getline(file, line)) 
        {
            std::istringstream iss(line);
            std::vector<std::string> columns;
            std::string column;
            while (std::getline(iss, column, ',')) 
            {
                columns.push_back(column);
            }
            createTable(tableName, columns);
        }

        Table* table = getTable(tableName);
        if (!table) return;

        while (std::getline(file, line)) 
        {
            std::istringstream iss(line);
            std::string value;
            Record record;
            int colIndex = 0;
            while (std::getline(iss, value, ',')) 
            {
                if (colIndex < table->columnNames.size()) 
                {
                    record.setField(table->columnNames[colIndex], value);
                    colIndex++;
                }
            }
            table->addRecord(record);
        }
        file.close();
    }
};

int main() 
{
    Database db;
    db.loadFromFile("employee", "employee_data.txt");

    db.createTable("students", {"ID", "Name", "Major"});
    Record student;
    student.setField("ID", "12345");
    student.setField("Name", "Alice");
    student.setField("Major", "Computer Science");
    db.addRecordToTable("students", student);

    auto results = db.queryTable("students", "Major", "Computer Science");
    for (const auto& record : results) 
    {
        std::cout << "ID: " << record.getField("ID") << ", Name: " << record.getField("Name") << std::endl;
    }

    db.deleteRecordFromTable("students", 0);
    db.deleteTable("students");

    return 0;
}

测试数据文件(employee_data.txt)

你需要创建一个文件employee_data.txt来存储雇员信息,例如:

Employee,Name,Department,Boss
111-11-1234,Cruz,ACC,Warder
213-44-5649,Johnston,MIS,Michaels
321-88-7895,Tom,FIN,Bearskin

运行步骤

  1. 确保C++编译器安装正确。
  2. 保存上述代码到一个文件,比如源.cpp
  3. 创建测试数据文件employee_data.txt,并将其内容按照上述格式填写。
  4. 进行编译运行程序

这样,你就可以看到程序的输出,验证各项功能是否正常工作。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值