精易论坛

标题: [C++ Qt] SQLite 数据库连接池 [打印本页]

作者: 希纱    时间: 2024-12-10 01:18
标题: [C++ Qt] SQLite 数据库连接池

特点如下:






  1. 单例模式



    • 使用单例模式确保全局只有一个连接池实例

    • 禁用了拷贝构造和赋值操作符




  2. 连接管理



    • 支持最大连接数限制 (m_maxConnections)

    • 支持初始连接数设置 (initialConnections)

    • 使用原子计数器 (m_connectionCounter) 跟踪连接总数

    • 维护可用连接队列 (m_availableConnections) 和使用中连接集合 (m_inUseConnections)




  3. 线程安全



    • 使用互斥锁保护共享资源

    • 使用条件变量实现等待/唤醒机制

    • 使用原子操作进行计数




  4. 智能指针管理



    • 使用 shared_ptr 自动管理连接的生命周期

    • DBConnection 析构时自动释放连接回连接池




  5. 连接复用机制



    • 优先使用可用连接

    • 当无可用连接且未达到最大连接数时创建新连接

    • 支持连接有效性检查和自动重连




  6. 错误处理



    • 连接创建失败时的回滚机制

    • 连接无效时的重新创建机制

    • 超时等待机制(5秒超时)




  7. 资源清理



    • 支持关闭所有连接

    • 正确处理事务回滚

    • 清理无效连接




  8. 数据库表管理



    • 支持表结构同步

    • 支持字段类型变更


    • 支持新增和删除字段






暂时没做其它功能, 有需求的同学自行扩展~


SqiiteUtils.zip

3.2 KB, 下载次数: 31, 下载积分: 精币 -2 枚


作者: 希纱    时间: 2024-12-10 01:19
嗯...多写点儿说明显得我很牛批
作者: bbb620    时间: 2024-12-10 01:32
高级货,占个位置先
作者: pipicool    时间: 2024-12-10 01:59
学习一下
作者: pshq123    时间: 2024-12-10 05:32
学习一下
作者: yuxuanju    时间: 2024-12-10 06:24
学习分享一下
作者: mmlai8    时间: 2024-12-10 07:11
学习分享一下
作者: qwe111qwe    时间: 2024-12-10 07:19
感谢分享!!!!
作者: Fate    时间: 2024-12-10 08:46
感谢分享
作者: 一指温柔    时间: 2024-12-10 09:20
感谢分享
作者: 杨明煜    时间: 2024-12-10 10:07
学习学习!........
作者: 396384183    时间: 2024-12-10 10:25

感谢分享,很给力!~
作者: 何浩文    时间: 2024-12-10 11:06
支持开源~!感谢分享
作者: xtavoxing    时间: 2024-12-10 13:09
支持开源~!感谢分享         YYDS~!
作者: 深圳梦    时间: 2024-12-10 16:30
支持开源~!感谢分享
作者: yuxuanju    时间: 2024-12-10 21:05
感谢分享学习。
作者: 希纱    时间: 2024-12-10 22:24
有点儿小修改, 改了一下同步表的逻辑, 现已支持复合主键:
bool SqliteUtils::SyncTable(const QString& tableName, const QMap<QString, FieldDefinition>& fieldDefinitions) {
    auto dbConnection = AcquireDBConnection();
    if (!dbConnection) {
        return false;
    }

    QSqlQuery sqlQuery(dbConnection->database());
    sqlQuery.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = :tableName");
    sqlQuery.bindValue(":tableName", tableName);

    if (!sqlQuery.exec()) {
        return false;
    }

    bool tableExists = sqlQuery.next();
    if (!tableExists) {
        QStringList fieldDefinitionList;
        QStringList primaryKeys;

        QString createTableSql = QString("CREATE TABLE %1 (").arg(tableName);
        for (auto it = fieldDefinitions.constBegin(); it != fieldDefinitions.constEnd(); ++it) {
            if (it.key() == "PRIMARY KEY") {
                if (!it.value().defaultValue.isEmpty()) {
                    primaryKeys.append(it.value().defaultValue);
                }
                continue;
            }

            QString fieldSql = QString("%1 %2").arg(it.key(), it.value().fieldType);

            if (it.value().notNull) {
                fieldSql += " NOT NULL";
            }

            if (!it.value().defaultValue.isEmpty()) {
                fieldSql += QString(" DEFAULT %1").arg(it.value().defaultValue);
            }

            if (it.value().isPrimaryKey) {
                fieldSql += " PRIMARY KEY";
            }

            fieldDefinitionList.append(fieldSql);
        }

        if (!primaryKeys.isEmpty()) {
            fieldDefinitionList.append(QString("PRIMARY KEY %1").arg(primaryKeys.join(", ")));
        }

        createTableSql += fieldDefinitionList.join(", ") + ")";
        return sqlQuery.exec(createTableSql);
    } else {
        sqlQuery.prepare(QString("PRAGMA table_info(%1)").arg(tableName));
        if (!sqlQuery.exec()) {
            return false;
        }

        bool requireUpdate = false;
        QMap<QString, QString> existingFieldTypes;
        while (sqlQuery.next()) {
            QString fieldName = sqlQuery.value(1).toString();
            QString fieldType = sqlQuery.value(2).toString();

            existingFieldTypes[fieldName] = fieldType;
            if (!fieldDefinitions.contains(fieldName)) {
                requireUpdate = true;
                continue;
            }

            if (fieldDefinitions[fieldName].fieldType.toUpper() != fieldType.toUpper()) {
                requireUpdate = true;
            }
        }

        for (auto it = fieldDefinitions.constBegin(); it != fieldDefinitions.constEnd(); ++it) {
            if (!existingFieldTypes.contains(it.key())) {
                requireUpdate = true;
                break;
            }
        }

        if (requireUpdate) {
            QString tempTableName = QString("%1_%2").arg(tableName).arg(QDateTime::currentMSecsSinceEpoch());

            QStringList selectFields;
            QStringList fieldDefinitionList;
            QStringList primaryKeys;
            QStringList actualFields;

            QString createTempTableSql = QString("CREATE TABLE %1 (").arg(tempTableName);
            for (auto it = fieldDefinitions.constBegin(); it != fieldDefinitions.constEnd(); ++it) {
                if (it.key() == "PRIMARY KEY") {
                    if (!it.value().defaultValue.isEmpty()) {
                        primaryKeys.append(it.value().defaultValue);
                    }
                    continue;
                }
                actualFields.append(it.key());

                QString fieldSql = QString("%1 %2").arg(it.key(), it.value().fieldType);

                if (it.value().notNull) {
                    fieldSql += " NOT NULL";
                }

                if (!it.value().defaultValue.isEmpty()) {
                    fieldSql += QString(" DEFAULT %1").arg(it.value().defaultValue);
                }

                if (it.value().isPrimaryKey) {
                    fieldSql += " PRIMARY KEY";
                }

                fieldDefinitionList.append(fieldSql);

                if (existingFieldTypes.contains(it.key())) {
                    if (it.value().fieldType.toUpper() == "INTEGER") {
                        selectFields.append(QString("CAST(ROUND(CASE WHEN %1 GLOB '*[0-9]*' THEN %1 ELSE 0 END) AS INTEGER) AS %1").arg(it.key()));
                    } else if (it.value().fieldType.toUpper() == "REAL") {
                        selectFields.append(QString("CAST(CASE WHEN %1 GLOB '*[0-9]*' THEN %1 ELSE 0 END AS REAL) AS %1").arg(it.key()));
                    } else if (it.value().fieldType.toUpper() == "TEXT") {
                        selectFields.append(QString("CAST(%1 AS TEXT) AS %1").arg(it.key()));
                    } else {
                        selectFields.append(it.key());
                    }
                } else {
                    if (!it.value().defaultValue.isEmpty()) {
                        selectFields.append(QString("%1 AS %2").arg(it.value().defaultValue, it.key()));
                    } else {
                        selectFields.append("NULL AS " + it.key());
                    }
                }
            }

            if (!primaryKeys.isEmpty()) {
                fieldDefinitionList.append(QString("PRIMARY KEY %1").arg(primaryKeys.join(", ")));
            }

            createTempTableSql += fieldDefinitionList.join(", ") + ")";
            if (!sqlQuery.exec(createTempTableSql)) {
                return false;
            }

            QString copyDataSql = QString("INSERT INTO %1 (%2) SELECT %3 FROM %4").arg(tempTableName, actualFields.join(", "), selectFields.join(", "), tableName);
            if (!sqlQuery.exec(copyDataSql)) {
                return false;
            }

            QString dropTableSql = QString("DROP TABLE IF EXISTS %1").arg(tableName);
            if (!sqlQuery.exec(dropTableSql)) {
                return false;
            }

            QString renameTableSql = QString("ALTER TABLE %1 RENAME TO %2").arg(tempTableName, tableName);
            return sqlQuery.exec(renameTableSql);
        } else {
            return true;
        }
    }
}
作者: year1970    时间: 2024-12-11 12:28
感谢分享
作者: 大墩墩    时间: 2024-12-11 14:46
666666666666666666666666666666666666666666
作者: 98小青年    时间: 2024-12-11 14:48
nbifdsffdgfdgdfgfdgdfgdf
作者: corking    时间: 2024-12-11 21:53
感谢分享!
作者: 吾爱学技术    时间: 2024-12-12 22:31
感谢分享,很给力!~
作者: xxbing    时间: 2024-12-15 08:31
学习数据库连接正需要
作者: 面具,    时间: 2025-2-11 10:48

作者: leaqi    时间: 2025-3-7 01:30





欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4