查看完整版本: [-- Qt数据库集成应用封装 --]

QTCN开发网 -> Qt 作品展 -> Qt数据库集成应用封装 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

liudianwu 2017-06-11 16:13

Qt数据库集成应用封装

平时的大大小小的项目中,基本上都需要与数据库打交道,会遇到各种各样的应用场景,本人主要遇到四种场景
1:数据库自动重连,例如mysql数据库中经常遇到服务器挂掉的情况,需要自动检测并重新连接数据库。
2:数据库自动清理早期数据,保证数据库中为最新的数据,而容量有限。
3:数据实时同步云端,客户端从云端同步数据到本地。
4:多线程批量执行sql语句。
为此,特意将各种应用场景封装成类,每个项目只需要传入对应参数即可。大大节省了开发时间。集成到pri文件中,每次项目引入即可。

DbTcpClientThread
/**
* 远程数据实时同步线程客户端,负责上传数据
* 1:可设置远程mysql数据库信息
* 2:自动重连数据库
* 3:可设置检测连接间隔
* 4:自动重置远程设备信息
* 5:所有消息都发送信号,可在信号槽函数中打印输出
*/

DbTcpServerThread
/**
* 远程数据实时同步线程服务端,负责下载数据
* 1:可设置远程mysql数据库信息
* 2:自动重连数据库
* 3:可设置检测连接间隔
* 4:可设置要查询的表名
* 5:所有消息都发送信号,可在信号槽函数中打印输出
* 6:返回数据结果严格按照字段顺序
* 7:返回的数据同时包含关键字字段数据
* 8:提供接口可对远程数据库执行sql语句
* 9:提供接口可对远程数据库获取对应表数据
*/

DbTcpDataThread
/**
* 本地数据同步到远程数据库线程
* 1:可设置远程mysql数据库信息
* 2:可设置本地mysql数据库信息
* 3:自动重连数据库,包括本地数据库和远程数据库
* 4:可设置检测连接间隔
* 5:所有消息都发送信号,可在信号槽函数中打印输出
* 6:支持优先执行sql语句
*/

DbWebServerThread
/**
* 远程数据实时同步线程服务端,负责下载数据
* 1:通过web方式访问网页获取返回值
* 2:可以拓展支持更多种支持方式
* 3:可设置检测连接间隔
* 4:可设置要查询的表名
* 5:所有消息都发送信号,可在信号槽函数中打印输出
* 6:返回数据结果严格按照字段顺序
* 7:返回的数据同时包含关键字字段数据
*/

DbCountThread
/**
* 数据库通用翻页类
* 1:自动按照设定的每页多少行数据分页
* 2:只需要传入表名/字段集合/每页行数/翻页指示按钮/文字指示标签
* 3:提供公共静态方法绑定字段数据到下拉框
* 4:建议条件字段用数字类型的主键,速度极快
* 5:增加线程查询符合条件的记录总数,数据量巨大时候不会卡主界面
*/

DbLocalThread
/**
* 本地数据库打开、关闭、检查、重连
* 1:支持数据库自动重连
* 2:可设置检查数据库时间间隔
*/

DbExecSqlThread
/**
* 批量执行sql语句线程类
* 1:可设置对应数据库连接名称和sql语句
* 2:执行结果提供信号传出执行是否成功,执行条数,用时
*/

DbDelegate
/**
* 自定义委托类
* 1:可设置多种委托类型,例如文本框/下拉框/日期框等
* 2:可设置文本框是否密文显示
* 3:可设置默认数据,包括下拉框数据集合
* 4:提供值变化信号,比方说下拉框值改动触发
*/

DbCleanThread
/**
* 自动清理数据类
* 1:可设置要清理的对应数据库连接名称和表名
* 2:可设置条件字段
* 3:可设置排序字段
* 4:可设置最大保留的记录数
* 5:可设置执行自动清理的间隔
* 6:后期支持多个数据库和多个表
* 7:建议条件字段用数字类型的主键,速度极快
* 8:增加统计用字段名称设置
*/
[attachment=17247]
[attachment=17248]
[attachment=17249]
[attachment=17250]
[attachment=17251]

liudianwu 2017-06-11 16:14
[attachment=17252]
[attachment=17253]
[attachment=17254]
[attachment=17255]

liuchangyin 2017-06-12 00:13

jsxyhyj 2017-06-13 14:39
相当不错

九重水 2017-06-13 16:06
数据库程序设计现在好像很吃香啊。什么大数据啊,云啊,

stlcours 2017-06-13 17:08
是开源还是卖钱?话说DbDelegate类有必要吗?客户可以自己设置啊。设置代理反而不灵活了。

pangwei 2017-06-14 08:38
http://www.qtdebug.com/qtbook-db-util/这个数据库操作的类也还可以

liudianwu 2017-06-14 12:15
pangwei:http://www.qtdebug.com/qtbook-db-util/这个数据库操作的类也还可以 (2017-06-14 08:38) 

公孙二狗现在搞java开发去了!

liuyuanan 2017-06-18 19:38
多节点数据存储及同步,建议使用Redis

lin617559770 2017-06-21 21:05
楼主你这个demo开源吗

apud 2017-07-13 21:28
楼主,一两年前我陆陆续续花了一两百块买过你几个源码,实在经典,学到不少东西。现有一个问题特来请教:使用qt连接阿里云的数据库,软件闲置几分钟再次操作数据库,显示mysql has gone away。这应该怎么解决,按照网上办法修改my.ini配置依然无效。软件要求效率高,所以不可能需要用到数据库操作时再次重连。也就是我希望它能长时间保持和数据库连接。

liudianwu 2017-07-14 08:29
apud:
楼主,一两年前我陆陆续续花了一两百块买过你几个源码,实在经典,学到不少东西。现有一个问题特来请教:使用qt连接阿里云的数据库,软件闲置几分钟再次操作数据库,显示mysql has gone away。这应该怎么解决,按照网上办法修改my.ini配置依然无效。软件要求效率高,所以不可能需要用到数据库操作时再次重连。也就是我希望它能长时间保持和数据库连接。

这个问题是mysql数据库的经典问题,貌似开源版本的就是存在这个问题,目前我们的水平很难从源码层更改mysql,只能定时判断数据库连接,然后一旦发现执行失败超过次数则说明数据库断开了连接,这样就重新连接数据库即可!
核心代码如下
  1. #include "dblocalthread.h"

    DbLocalThread *DbLocalThread::self = 0;
    DbLocalThread::DbLocalThread(QObject *parent) : QThread(parent)
    {
        stopped = false;

        dbOkLocal = false;
        lastCheckTimeLocal = QDateTime::currentDateTime();
        checkInterval = 30;

        dbTypeLocal = DbType_MySql;
        connNameLocal = "qt_sql_default_connection";
        hostNameLocal = "127.0.0.1";
        portLocal = 3306;
        dbNameLocal = "tcms_liu_mysql";
        userNameLocal = "root";
        userPwdLocal = "root";    
    }

    void DbLocalThread::run()
    {
        while (!stopped) {
            //定时执行一次校验数据库连接是否正常
            QDateTime now = QDateTime::currentDateTime();

            if (lastCheckTimeLocal.secsTo(now) >= checkInterval) {
                checkDb();
                lastCheckTimeLocal = now;
                continue;
            }

            //如果数据库连接正常则处理数据,不正常则重连数据库
            if (!dbOkLocal) {
                openDb();
                emit debug(QString("重连数据库%1").arg(dbOkLocal ? "成功" : "失败"));
                msleep(3000);
            } else {
                msleep(1000);
            }
        }

        stopped = false;
    }

    bool DbLocalThread::openDb()
    {
        //可以自行增加其他数据库的支持
        if (dbTypeLocal == DbType_Sqlite) {
            dbConnLocal = QSqlDatabase::addDatabase("QSQLITE", connNameLocal);
            dbConnLocal.setDatabaseName(dbNameLocal);
        } else if (dbTypeLocal == DbType_MySql) {
            dbConnLocal = QSqlDatabase::addDatabase("QMYSQL", connNameLocal);
            dbConnLocal.setHostName(hostNameLocal);
            dbConnLocal.setPort(portLocal);
            dbConnLocal.setDatabaseName(dbNameLocal);
            dbConnLocal.setUserName(userNameLocal);
            dbConnLocal.setPassword(userPwdLocal);
        }

        dbOkLocal = dbConnLocal.open();
        return dbOkLocal;
    }

    bool DbLocalThread::checkDb()
    {
        QDateTime dtStart = QDateTime::currentDateTime();

        QString sql = "select 1";
        QSqlQuery query(dbConnLocal);
        dbOkLocal = query.exec(sql);

        QDateTime dtEnd = QDateTime::currentDateTime();
        double ms = dtStart.msecsTo(dtEnd);
        emit debug(QString("检查数据库连接(共 %1 条/用时 %2 秒)").arg(1).arg(QString::number(ms / 1000, 'f', 3)));

        return dbOkLocal;
    }

    void DbLocalThread::closeDb()
    {
        dbConnLocal.close();
        QSqlDatabase::removeDatabase(connNameLocal);
        dbOkLocal = false;
        emit debug("关闭数据库");
    }

    void DbLocalThread::stop()
    {
        stopped = true;
    }

    void DbLocalThread::setConnInfo(DbLocalThread::DbType dbType, const QString &connName, const QString &hostName, int port, const QString &dbName, const QString &userName, const QString &userPwd)
    {
        this->dbTypeLocal = dbType;
        this->connNameLocal = connName;
        this->hostNameLocal = hostName;
        this->portLocal = port;
        this->dbNameLocal = dbName;
        this->userNameLocal = userName;
        this->userPwdLocal = userPwd;
    }

    void DbLocalThread::setCheckInterval(int checkInterval)
    {
        if (checkInterval > 5 && this->checkInterval != checkInterval) {
            this->checkInterval = checkInterval;
        }
    }


apud 2017-07-14 20:32
非常感谢,我学习下。我记得之前使用阿里云的另一个套餐的数据库并没有这个问题。换了ECS服务器,自己windows server 2008装了个数据库就存在这个问题。如果用这个方法重连的话,是否对效率有影响。

liudianwu 2017-07-14 21:04
apud:非常感谢,我学习下。我记得之前使用阿里云的另一个套餐的数据库并没有这个问题。换了ECS服务器,自己windows server 2008装了个数据库就存在这个问题。如果用这个方法重连的话,是否对效率有影响。 (2017-07-14 20:32) 

完全没有影响,因为是多线程,丝毫不会内存泄漏!Qt对数据库的封装还是非常完美的,采用了连接名称作为处理标识符。

apud 2017-07-15 07:09
OK。顺便问一下。你这源码可以购买吗?
我挺感兴趣的,想支持一下大神。
建议你可以开一个淘宝店,这样购买源码也方便点。

apud 2017-07-25 09:46
liudianwu:这个问题是mysql数据库的经典问题,貌似开源版本的就是存在这个问题,目前我们的水平很难从源码层更改mysql,只能定时判断数据库连接,然后一旦发现执行失败超过次数则说明数据库断开了连接,这样就重新连接数据库即可!
核心代码如下#include "dblocalthread.h"
DbL .. (2017-07-14 08:29) 

用这种方法遇到的一个问题,程序运行几分钟后,刚好过了30秒,程序判断数据库连接正常,没有进行重连操作。然后过了几秒 ,我进行了数据库操作,就gone away了。也就是保险的方法还是要  需要操作数据库的时候强制重连。

liudianwu 2017-07-25 13:06
apud:用这种方法遇到的一个问题,程序运行几分钟后,刚好过了30秒,程序判断数据库连接正常,没有进行重连操作。然后过了几秒 ,我进行了数据库操作,就gone away了。也就是保险的方法还是要  需要操作数据库的时候强制重连。 (2017-07-25 09:46) 

嗯,是的,你可以采取短连接的方式进行数据库操作。每次操作数据库都是重新连接数据库,执行完后断开数据库,不过这样费时间,不建议。我的处理是一个线程实时判断是否正常,不正常则重新连接数据库,如果执行sql语句的地方执行失败,则将失败的语句存起来,等连接恢复正常后自动执行。

apud 2017-07-26 08:15
[attachment=17563]
请教下,用你那套7色QSS样式表 制作的软件,有的时候打开出现这种情况。显示 未响应,然后自定义的界面没有显示出来。我好像很久之前偶尔碰到过一两次这种情况,软件给其它用户使用,有两个人已经反应有这个问题,但是一般 重启电脑就OK了。

whhitfk 2017-08-14 11:24
楼主源码开源吗? 有没有源码发一份啊  万分感谢,whhitfk@163.com

stlcours 2017-08-14 20:13
liuyuanan:多节点数据存储及同步,建议使用Redis (2017-06-18 19:38) 

有没有想关的文章可以学习一下啊??

clickto 2017-10-24 10:49
先mark一下

clickto 2017-10-25 11:22
附议!!!

lengji22 2017-10-30 16:59
pangwei:http://www.qtdebug.com/qtbook-db-util/这个数据库操作的类也还可以 (2017-06-14 08:38) 

看了喜爱,很好的数据库操作

apud 2017-12-19 09:15
问个问题。一般公司用Qt开发软件,连接数据库,是在程序里面直接操作SQL吗?还是通过服务端提供接口的方式操作数据库?因为前者开发的软件通过抓包,可以抓到所有SQL操作语句,会暴露数据库字段等信息,如果软件又是直接用SQL原生操作,没有进行参数绑定等操作,就有SQL注入漏洞,又暴露了字段,很容易就被黑了。

liudianwu 2017-12-19 10:33
apud:问个问题。一般公司用Qt开发软件,连接数据库,是在程序里面直接操作SQL吗?还是通过服务端提供接口的方式操作数据库?因为前者开发的软件通过抓包,可以抓到所有SQL操作语句,会暴露数据库字段等信息,如果软件又是直接用SQL原生操作,没有进行参数绑定等操作,就有SQL注入漏洞, .. (2017-12-19 09:15) 

多写过滤就不会有注入了!

apud 2017-12-19 10:40
那暴露字段问题怎么解决?另外我之前看过你那个视频监控的源码,里面SQL操作好像都是直接拼接SQL后exec执行的,没看到有过滤的地方。

adon1008 2020-08-17 23:05
pangwei:http://www.qtdebug.com/qtbook-db-util/这个数据库操作的类也还可以 (2017-06-14 08:38) 

楼主有资源吗?刚去看下载不了了

libaineu2004 2020-09-22 15:12
http://qtdebug.com/qtbook-db-util/


查看完整版本: [-- Qt数据库集成应用封装 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled