数据库-ODBC操作

承接Qt/C++软件开发项目,高质量交付,灵活沟通,长期维护支持。需求所寻,技术正适,共创完美,欢迎私信联系!

一、ODBC 数据源配置

打开ODBC数据源管理器:

  • 在Windows搜索栏中键入“ODBC数据源”并选择“ODBC数据源(64位)”(如果你的系统是64位的)。
  • 如果你的系统是32位的,你可以选择“ODBC数据源(32位)”。
  • 或者,你可以在控制面板中找到ODBC数据源管理器。

    添加数据源:

    • 在ODBC数据源管理器中,选择“用户DSN/系统DSN”选项卡。
    • 点击“添加”按钮,在弹出的对话框中选择要配置的数据库类型(如SQLite、MySQL等)。
    • 根据数据库类型和具体的配置要求填写相应的信息,例如数据库文件路径、服务器名称、用户名、密码等。
    • 完成配置后,点击“确定”按钮。

      二、使用ODBC的优点和缺点

      优点:

              平台独立性:ODBC提供了一种标准的API,使得应用程序可以在不同的操作系统上连接和操作数据库,从而实现了一定程度的平台独立性。

              数据库透明性:通过ODBC,应用程序可以通过相同的API连接到不同类型的数据库,无论是关系型数据库还是非关系型数据库,这增加了灵活性和可扩展性。

              易于维护:ODBC提供了一种标准的接口,使得数据库连接和操作可以在不修改应用程序代码的情况下进行配置和更改。这使得维护和管理数据库连接变得更加简单。

              大量的驱动支持:由于ODBC已经成为了一种行业标准,几乎所有的主流数据库供应商都提供了ODBC驱动程序,因此你可以很容易地连接到各种不同类型的数据库。

      缺点:

              性能损失:与直接使用特定数据库的本地API相比,通过ODBC连接数据库可能会带来一定的性能损失,因为它涉及到额外的数据转换和通信开销。

              功能限制:由于ODBC只提供了一种标准的API,因此某些特定于数据库引擎的功能可能无法直接通过ODBC访问,你可能需要使用特定数据库的本地API来实现这些功能。

              连接和配置复杂性:配置和管理ODBC数据源可能需要一些额外的工作,特别是对于一些复杂的数据库配置,可能需要更多的时间和精力。

              平台依赖性:虽然ODBC提供了一定程度的平台独立性,但在不同的操作系统上可能会有一些细微的差异,这可能需要在跨平台应用程序中进行一些额外的处理。

      三、实现操作代码

      创建了一个名为DatabaseManager的类,其中分为通过ODBC数据源模式和直接ODBC访问数据库模式,注意代码注释内容。

      #ifndef DATABASEMANAGER_H
      #define DATABASEMANAGER_H
      #include #include #include typedef struct{
          QString username;
          QString password;
          QString databaseName;
          QString serverName;
          QString driverName;
      }T_Database;
      /*
       * 数据库操作管理类
       */
      class  DatabaseManager : public QObject
      {
          Q_OBJECT
      public:
          DatabaseManager(QObject *parent = nullptr);
          ~DatabaseManager();
          // 打开数据库
          bool openDB(const T_Database &data);
          // 关闭数据库
          void closeDB();
          // 数据库是否有效
          bool isDatabaseValid();
          // 判断字段值是否存在
          bool isExistsValue(const QString& tableName, const QString& condition);
          // 创建表
          bool createTable(const QString& createSql);
          // 插入数据
          bool insertData(const QString& tableName, const QMap& data);
          // 删除数据
          bool deleteData(const QString& tableName, const QString& condition);
          // 更新数据
          bool updateData(const QString& tableName, const QString& condition, const QMap& data);
          // 查询数据
          bool queryData(const QString& tableName, const QString& condition, QList>& data);
       
      private:
          QSqlDatabase m_db;
      };
      #endif // DATABASEMANAGER_H
      
      #include "databasemanager.h"
      #include #include #include #include #pragma execution_character_set("utf-8")
      DatabaseManager::DatabaseManager(QObject* parent)
          : QObject(parent)
      {
      }
      DatabaseManager::~DatabaseManager()
      {
      }
      bool DatabaseManager::openDB(const T_Database &data)
      {
          if (isDatabaseValid())
          {
              return true;
          }
          m_db = QSqlDatabase::addDatabase("QODBC");
          if (!m_db.isValid())
          {
              QStringList drivers = QSqlDatabase::drivers();
              qDebug() << "drivers: " << drivers;
              qCritical() << "Failed to load QODBC driver. " << m_db.lastError().text();
              return false;
          }
          
          // 方法一、连接到ODBC数据源 
          // m_db.setDatabaseName(dataSourceName);
          
          // 方法二、直接通过ODBC连接数据库
          QString connectionString = QString("DRIVER={%1};SERVER=%2;DATABASE=%3;UID=%4;PWD=%5;PORT=%6;")
                  .arg(data.driverName)
                  .arg(data.serverName)
                  .arg(data.databaseName)
                  .arg(data.username)
                  .arg(data.password)
                  .arg(data.serverPort);
          m_db.setDatabaseName(connectionString);
       
          if (!m_db.open())
          {
              qCritical() << "Error: Failed to connect to database." << m_db.lastError().text();
              return false;
          }
          return true;
      }
      void DatabaseManager::closeDB()
      {
          if (m_db.isOpen())
          {
              m_db.close();
          }
      }
      bool DatabaseManager::isDatabaseValid()
      {
          return (m_db.isOpen() || m_db.isValid());
      }
      bool DatabaseManager::isExistsValue(const QString& tableName, const QString& condition)
      {
          QString sql = QString("SELECT * FROM %2").arg(tableName);
          if(!condition.isEmpty())
          {
              sql += " " + condition;
          }
          QSqlQuery selectQuery;
          selectQuery.prepare(sql);
          // 绑定参数或拼接查询条件
          // selectQuery.bindValue(...);
          if (!selectQuery.exec())
          {
              qCritical() << "Error: Failed to select data from the database. " << selectQuery.lastError().text();
              return false;
          }
          if (selectQuery.next())
          {
              // 字段的值存在
              // 执行相应的逻辑
              // ...
              return true;
          }
          // 字段的值不存在
          // 执行相应的逻辑
          // ...
          //
          return false;
      }
      bool DatabaseManager::createTable(const QString& createSql)
      {
          if (!isDatabaseValid())
          {
              qCritical() << "Error: Database connection is not valid.";
              return false;
          }
          qDebug() << "createTable: " << createSql;
          QSqlQuery query;
          if (!query.exec(createSql))
          {
              qCritical() << "Error: Failed to create table.";
              return false;
          }
          query.finish();
          return true;
      }
      bool DatabaseManager::insertData(const QString& tableName, const QMap& data)
      {
          if (!isDatabaseValid())
          {
              qCritical() << "Error: Database is not valid.";
              return false;
          }
          QString sql = "INSERT INTO " + tableName + " (";
          QString values = "VALUES (";
          // 构建字段列表和值列表
          QStringList fields;
          QStringList placeholders;
          for (const auto& key : data.keys())
          {
              fields << key;
              placeholders << ":" + key;
          }
          sql += fields.join(", ") + ") ";
          values += placeholders.join(", ") + ")";
          QSqlQuery query;
          query.prepare(sql + values);
          // 绑定参数
          for (const auto& key : data.keys())
          {
              query.bindValue(":" + key, data.value(key));
          }
          qDebug() << "insertData: " << sql + values;
          if (!query.exec())
          {
              qCritical() << "Error: Failed to insert data into database. " << query.lastError().text();
              return false;
          }
          query.finish();
          return true;
      }
      bool DatabaseManager::deleteData(const QString& tableName, const QString& condition)
      {
          if (!isDatabaseValid())
          {
              qCritical() << "Error: Database is not valid.";
              return false;
          }
          QString sql = "DELETE FROM " + tableName + " " + condition;
          qDebug() << "deleteData: " << sql;
          QSqlQuery query;
          query.prepare(sql);
          if (!query.exec())
          {
              qCritical() << "Error: Failed to delete data from database. " << query.lastError().text();
              return false;
          }
          return true;
      }
      bool DatabaseManager::updateData(const QString& tableName, const QString& condition,
                                       const QMap& data)
      {
          if (!isDatabaseValid())
          {
              qCritical() << "Error: Database is not valid.";
              return false;
          }
          QString sql = "UPDATE " + tableName + " SET ";
          // 构建更新字段列表
          QStringList updates;
          for (const auto& key : data.keys())
          {
              updates << key + " = :" + key;
          }
          sql += updates.join(", ") + " " + condition;
          qDebug() << "updateData: " << sql;
          QSqlQuery query;
          query.prepare(sql);
          // 绑定参数
          for (const auto& key : data.keys())
          {
              query.bindValue(":" + key, data.value(key));
          }
          if (!query.exec())
          {
              qCritical() << "Error: Failed to update data in database. " << query.lastError().text();
              return false;
          }
          query.finish();
          return true;
      }
      bool DatabaseManager::queryData(const QString& tableName, const QString& condition,
                                      QList>& data)
      {
          if (!isDatabaseValid())
          {
              qCritical() << "Error: Database is not valid.";
              return false;
          }
          QString sql = "SELECT * FROM " + tableName;
          if (!condition.isEmpty())
          {
              sql += " " + condition;
          }
          qDebug() << "queryData: " << sql;
          QSqlQuery query(sql);
          while (query.next())
          {
              QMap row;
              QSqlRecord record = query.record();
              for (int i = 0; i < record.count(); i++)
              {
                  QString fieldName = record.fieldName(i);
                  QVariant value = query.value(i);
                  row.insert(fieldName, value);
              }
              data.append(row);
          }
          query.finish();
          return true;
      }