• 1521阅读
  • 20回复

[提问]饶了我,MySQL! [复制链接]

上一主题 下一主题
离线介农酥
 

只看楼主 正序阅读 楼主  发表于: 2024-07-24
回复本帖可获得15RMB金钱奖励!
每人最多可获奖1次,奖池剩余0RMB金钱 (中奖几率90%)
客户现场工控机环境:Windows7  MySQL8.0.31 Qt5.15.2
开发环境:Windows11 MySQL8.0.31 Qt5.15.2

最近问了一系列跟数据使用和ssl的问题,我只能怪我学艺不精。

最开始的时候程序总是崩溃,dump文件显示数据库ssl有问题,最后出问题的是libssl_1_1_x64!SSL_SESSION_set1_hostname+0xac1b这一句。一开始我认为是自己数据库写的不对,后面我改了很久的代码,问题最终也没有解决,还是崩溃,最后我准备将程序放到工控机上运行,但是发现https第二次请求总是指向ssl错误,突然,我又想到干脆关闭mysql的ssl,最后折腾了下mysql,重装了mysql,数据也丢了,终于关闭了ssl验证,果然,程序连续几天不崩溃,我认为问题应该解决了,哪知当晚客户告诉我,设备有问题,我看了下数据没有插进去,我去看了下程序,控制台输出 数据库失去了连接,我在想应该是偶然的吧,到了晚上,我发现过几个小时就会断开连接,白天白班不忙的时候,我过段时间去看下,发现连接都还可以,一到了晚上夜班繁忙的时候,就经常断。我终于知道这是一个问题,我急急忙忙每一个查询前面都加了如下代码:

    if (db1.isOpen() == false)
        openDataBase();
不一会儿,发现不行,我又搜索了下网络,赶紧看了下qt的手册,发现了数据库有些选项可以设置,连ssl也可以设置,由于不懂,时间也很晚,生产又比较赶,我又加了下面的这一行:
db2.setConnectOptions("MYSQL_OPT_RECONNECT=1");
看看了时间,已经晚上11点多了,就回去了,想着估计也是没有用,但是心理还是抱着侥幸的。
第二天,起来,看群里,果然还是没用,我早上来到设备,看了下数据库,果然,在我走后不久,数据就没插入了。


void Database::openDataBase2()
{
    db2.setConnectOptions("MYSQL_OPT_RECONNECT=1");
    db2.setHostName("127.0.0.1");
    db2 = QSqlDatabase::addDatabase("QMYSQL", "2");
    db2.setDatabaseName("zhu-hai_gao-lan-gang_gree_label");
    //db2 = QSqlDatabase::addDatabase("QODBC", "2");  
    //db2.setDatabaseName("singsun");
    db2.setUserName("root");
    db2.setPassword("8ik,9ol");
    bool ok = db2.open();
    if (!ok) {
        QString errStr = db2.lastError().text();
        emit sigError("数据库2打开失败:" + errStr, "database");
        emit sigAll("数据库2打开失败:" + errStr, "database");
    } else {
        emit sigError("数据库2打开成功", "database");
        emit sigAll("数据库2打开成功", "database");
    }
}

db2运行在线程了,db1在主线程,后面的查询都是直接使用db2或者db1。

我目前想着是不用Qt的方法,使用mysql自带的访问和查询数据库的方式。
或者换数据库?或者降低mysql的版本5.7?

各位有什么建议感激不尽!
离线tanyue.esec

只看该作者 20楼 发表于: 2024-11-12
回 mugua001 的帖子
mugua001:哪个好用?请推荐一个,谢谢。 (2024-11-10 17:58) 

要看你对应qt的版本,64位还是32位的
离线mugua001

只看该作者 19楼 发表于: 2024-11-10
回 tanyue.esec 的帖子
tanyue.esec:gtihub上可以直接下载各种版本的MySQL驱动,找到qt对应的版本的就行 (2024-07-29 14:10) 

哪个好用?请推荐一个,谢谢。
离线mugua001

只看该作者 18楼 发表于: 2024-10-18
这里要留个脚印,说不定哪天就碰上了。
离线zeuwas

只看该作者 17楼 发表于: 2024-08-20
谢谢各位提供的帮助
离线tanyue.esec

只看该作者 16楼 发表于: 2024-08-11
回 zeuwas 的帖子
zeuwas:我之前也为这个驱动的事情苦恼了很久,有网址吗,我去看看
 (2024-08-08 09:53) 

不过还是自己编译源码最靠谱
离线tanyue.esec

只看该作者 15楼 发表于: 2024-08-11
回 zeuwas 的帖子
zeuwas:我之前也为这个驱动的事情苦恼了很久,有网址吗,我去看看
 (2024-08-08 09:53) 

https://github.com/thecodemonkey86/qt_mysql_driver
离线20091001753

只看该作者 14楼 发表于: 2024-08-10
回 zeuwas 的帖子
zeuwas:我之前也为这个驱动的事情苦恼了很久,有网址吗,我去看看
 (2024-08-08 09:53) 

Qt 6 编译 MySQL 驱动
http://www.qtcn.org/bbs/read-htm-tid-91447.html
(づ ̄ 3 ̄)づ
离线zeuwas

只看该作者 13楼 发表于: 2024-08-08
回 tanyue.esec 的帖子
tanyue.esec:gtihub上可以直接下载各种版本的MySQL驱动,找到qt对应的版本的就行 (2024-07-29 14:10)

我之前也为这个驱动的事情苦恼了很久,有网址吗,我去看看
离线tanyue.esec

只看该作者 12楼 发表于: 2024-07-29
gtihub上可以直接下载各种版本的MySQL驱动,找到qt对应的版本的就行
离线介农酥

只看该作者 11楼 发表于: 2024-07-29
回 liudianwu 的帖子
liudianwu:个人猜测你可能dll版本或者qt对应mysql驱动版本低于你用的mysql版本导致的,一般向下兼容,低版本无法兼容高版本。我也用这个8.0.31,完全正常。之前也是遇到过你的类似问题,后面重新用8.0.31的库重新编译了qt的数据库驱动就好了。17-数据库组件/多线程读写/自动重连/数据清理/数 .. (2024-07-25 08:43) 

厉害!非常感谢您的回答,我看看驱动是不是要重新编译。
离线liudianwu

只看该作者 10楼 发表于: 2024-07-25
个人猜测你可能dll版本或者qt对应mysql驱动版本低于你用的mysql版本导致的,一般向下兼容,低版本无法兼容高版本。我也用这个8.0.31,完全正常。之前也是遇到过你的类似问题,后面重新用8.0.31的库重新编译了qt的数据库驱动就好了。17-数据库组件/多线程读写/自动重连/数据清理/数据上传    https://qtchina.blog.csdn.net/article/details/118326074
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线介农酥

只看该作者 9楼 发表于: 2024-07-24
回 圣域天子 的帖子
圣域天子:Oracle,SQLServer,PostgreSQL 都很好用,但我就是不愿意碰 MySQL(Mariadb) 这个玩意儿 (2024-07-24 17:01) 

了解了,谢谢!
离线圣域天子

只看该作者 8楼 发表于: 2024-07-24
回帖奖励+ 15
Oracle,SQLServer,PostgreSQL 都很好用,但我就是不愿意碰 MySQL(Mariadb) 这个玩意儿
离线介农酥

只看该作者 7楼 发表于: 2024-07-24
回 angelus 的帖子
angelus://公共链接数据库类
Dmysql::Dmysql(QString prefix,QObject *parent) : QObject(parent)
{
    //缓存连接别名
    m_prefix = prefix;
....... (2024-07-24 11:06) 

离线angelus

只看该作者 6楼 发表于: 2024-07-24
//公共链接数据库类
Dmysql::Dmysql(QString prefix,QObject *parent) : QObject(parent)
{
    //缓存连接别名
    m_prefix = prefix;
}

//析构函数
Dmysql::~Dmysql()
{
    //断开数据库连接
    this->closeConnect();
}

//新建立数据库链接
bool Dmysql::initCon()
{
    QSqlDatabase db;
    if(!QSqlDatabase::contains(m_prefix))
    {
        QJsonObject config = AppGlobal::m_config;
        //新建 数据库实例
        db = QSqlDatabase::addDatabase("QMYSQL", m_prefix);
        db.setHostName(config.value("dbAddress").toVariant().toString());
        db.setPort(config.value("dbPort").toVariant().toInt());
        db.setUserName(config.value("dbUser").toVariant().toString());
        db.setPassword(config.value("dbPasswd").toVariant().toString());
        db.setDatabaseName(config.value("dbName").toVariant().toString());
    }
    else
    {
        db = QSqlDatabase::database(m_prefix);
    }
    //连接数据库
    if(!db.isOpen())
    {
        if(!db.open())
        {
            m_err = db.lastError().databaseText();
            qDebug() << m_err;
            closeConnect();
            return false;
        }
    }
    return true;
}

//断开数据库连接
void Dmysql::closeConnect()
{
    QSqlDatabase::database(m_prefix).close();
    QSqlDatabase::removeDatabase(m_prefix);
}

//清理所有连接
void Dmysql::closeAllConnections()
{
    QStringList connNames = QSqlDatabase::connectionNames();
    foreach(QString connName, connNames)
    {
        if(QSqlDatabase::contains(connName))
        {
            QSqlDatabase::database(connName).close();
            QSqlDatabase::removeDatabase(connName);
        }
    }
}

//执行多条语句
bool Dmysql::execSqls(const QStringList &array)
{
    m_err = "";
    if(!this->initCon()) return false;

    //启动事务操作
    bool ok = true;
    QSqlDatabase db = QSqlDatabase::database(m_prefix);
    if(db.transaction())
    {
        //查询数据局
        QSqlQuery query(QSqlDatabase::database(m_prefix));
        query.setForwardOnly(true);
        for(int i = 0; i < array.count(); ++i)
        {
            QString sql = array.at(i);
            if(!query.exec(sql))
            {
                m_err = sql + " ---- " + query.lastError().text();
                qInfo() << m_err;
                ok = false;
                break;
            }
        }
        //判断是否提交事务
        if(ok)
        {
            if(!db.commit())
            {
                qInfo() << "错误:事务提交失败:" + query.lastError().text();
            }
        }
        else
        {
            qInfo() << "错误:批量执行插入语句失败,回滚操作!";
            if(!db.rollback())
            {
                qInfo() << "错误:事务回滚失败:" + query.lastError().text();
            }
        }
    }
    else
    {
        qInfo() << "错误:批量执行插入语句启动事务失败! ";
        return false;
    }
    return ok;
}

我自己用的类,你可以参考下
离线介农酥

只看该作者 5楼 发表于: 2024-07-24
回 angelus 的帖子
angelus:我都是一次操作,就连接一次数据库的,没有用数据库指针,直接实例的类,函数结束,类就清理了,这样虽然每次操作都要先连接库,但可以保证每次操作前,都是干净的
数据库的连接dll可以直接下载第三方编译好,ssl这块还没出过问题
https://github.com/thecodemonkey86/qt_mysql_d .. (2024-07-24 10:53) 

我是自己编译的,最开始用的是ODBC,后面用的是dll,但是都解决不了问题。
离线介农酥

只看该作者 4楼 发表于: 2024-07-24
回 liulin188 的帖子
liulin188:我从来都不用qt 数据库那套东西,我都是直接原始api (2024-07-24 10:55) 

那你用了之后,是不是就是不崩了,或者断开了?
离线介农酥

只看该作者 3楼 发表于: 2024-07-24
回 angelus 的帖子
angelus:我都是一次操作,就连接一次数据库的,没有用数据库指针,直接实例的类,函数结束,类就清理了,这样虽然每次操作都要先连接库,但可以保证每次操作前,都是干净的 (2024-07-24 10:53) 

这样倒也可以哦。这样比较简单,不如先按你这样的,谢谢!
离线liulin188

只看该作者 2楼 发表于: 2024-07-24
回帖奖励+ 15
我从来都不用qt 数据库那套东西,我都是直接原始api
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线angelus

只看该作者 1楼 发表于: 2024-07-24
回帖奖励+ 15
我都是一次操作,就连接一次数据库的,没有用数据库指针,直接实例的类,函数结束,类就清理了,这样虽然每次操作都要先连接库,但可以保证每次操作前,都是干净的

数据库的连接dll可以直接下载第三方编译好,ssl这块还没出过问题
https://github.com/thecodemonkey86/qt_mysql_driver/releases?page=5

快速回复
限100 字节
 
上一个 下一个