一. 内容简介

QT多线程调用mysql存储数据。

二. 软件环境

2.1QT 5.14.1

新版QT6.4,,6.5在线安装经常失败,而5.9版本又无法编译64位程序,所以就采用5.14.1这个用的比较多也比较稳定的一个版本。

QT编译器采用的是MSVC2017 64bit。

链接:https://pan.baidu.com/s/1ER98DPAkTUPlIyCC6osNNQ?pwd=1234

2.2Mysql

mysql Ver 8.0.31 for Win64 on x86_64 (MySQL Community Server - GPL)

2.3SQLyog

qt sqlite3 多线程 qt多线程数据库_qt

三.主要流程

3.1 介绍数据类型,以及处理办法,以及存储办法

3.2 多线程调用

四.具体步骤

4.1 介绍数据类型,以及处理办法,以及存储办法

数据是一行五千多列(也可能在六七千,预留一部分)的数据,一次存储两条这样的数据。
首先需要创建数据表,mysql数据库一张表的列是小于1000的,所以我就将这五千列数据存储在十张表,一张九百零一列(多的一列为ID),多的表是预留,可以存更多列。
这样九百列的表创建起来也不容易(一开始打算手打…),具体创建过程可以参照(QT调用mysql数据表存储数据,mysql创建多列大表)。可以结合起来看,我的整个数据库代码就在这了,里面也有好多费代码,懒得改了,都放这了,
链接:https://pan.baidu.com/s/1Y_yC8bq5lbpcvaVXRCrlNg?pwd=1234

可能大家要问了,为什么不一下子添加一条数据,这个我也试了,方法列一下
这个有点麻烦,因为需要填入的数据太多了,句子太长了(我一开始也是想手写的),解决办法哈,我是用javascript写的脚本拼接的语句,软件用的vscode,给电脑装个node环境就可以运行了(安装步骤),好了就在终端中输入node xxx.js即可

let a = "";
let b = ""

for (var i = 1; i <= 900; i++) {
     a = ".arg(matrix1_h[" + i + "+(i-1)*900" + "])";
     b = b + a;
 }
 console.log(b)

qt sqlite3 多线程 qt多线程数据库_数据_02
当你语句写完后,放到qt中会发现,运行的很卡很慢,还没这个效果好,个人猜想哈,因为要将变量一个个拼接进语句反而更吃资源,z
运行完事后,可以看到时间花了13秒
qt sqlite3 多线程 qt多线程数据库_i++_03

4.2 多线程调用

开始多线程处理,多线程程序设计,多线程存储时候有个问题,就是一个连接对象(就是这个db)只能给一个线程用,不能共享,所以要加一个QString::number((quint64)QThread::currentThreadId()),这个是线程名字,这样就不会报错了。细节都在代码里面了,就提一下几个点,里面的model,model1是一个线程存完一个表900列数,model2和model==3,相当于两个线程合作存这个表,456相当于三个线程合作,
myThread_1(double num_p[902],double num_h[902],int Id,QString dataSheet,int model),前边都是数据,后两个,一个代表存那个表,一个就是选的模式了,是一个线程存一个表,还是多个线程存一个表。数据都是902的数组,这个传给线程的就是要存的,

class myThread_1: public QRunnable
{

    void run() override
    {
        // 给线程创建连接
        db = QSqlDatabase::addDatabase("QODBC",QString::number((quint64)QThread::currentThreadId()));
//        db = QSqlDatabase::addDatabase("QMYSQL",QString::number((quint64)QThread::currentThreadId()));
        db.setHostName("127.0.0.1");
        db.setPort(3306);
        db.setDatabaseName("QT");// 不是Database,记得别填错
        db.setUserName("root");
        db.setPassword("1234");
        bool ok = db.open();
        if (ok){
             qDebug()<<"thread-"<<"-successed" ;
        }
        else {
             qDebug()<<"thread-one-failed";
        }

        // 中间是需要存储的数据
        query=QSqlQuery(db);
        if(model == 1){
            for (int i=1;i<=900;i++) {
                // outh_1 outp_1
                if(i>count){
                    break;
                }
                sq_h=QString("UPDATE outh_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_h[i]).arg(Id);
                query.exec(sq_h);
                sq_p=QString("UPDATE outp_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_p[i]).arg(Id);
                query.exec(sq_p);
            }
        }
        if(model == 2){
            for (int i=1;i<=450;i++) {
                // outh_1 outp_1
                if(i>count){
                    break;
                }
                sq_h=QString("UPDATE outh_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_h[i]).arg(Id);
                query.exec(sq_h);
                sq_p=QString("UPDATE outp_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_p[i]).arg(Id);
                query.exec(sq_p);
            }
        }
        if(model == 3){
            for (int i=451;i<=900;i++) {
                // outh_1 outp_1
                if(i>count){
                    break;
                }
                sq_h=QString("UPDATE outh_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_h[i]).arg(Id);
                query.exec(sq_h);
                sq_p=QString("UPDATE outp_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_p[i]).arg(Id);
                query.exec(sq_p);
            }
        }
        if(model == 4){
            for (int i=1;i<=300;i++) {
                // outh_1 outp_1
                if(i>count){
                    break;
                }
                sq_h=QString("UPDATE outh_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_h[i]).arg(Id);
                query.exec(sq_h);
                sq_p=QString("UPDATE outp_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_p[i]).arg(Id);
                query.exec(sq_p);
            }
        }
        if(model == 5){
            for (int i=301;i<=600;i++) {
                // outh_1 outp_1
                if(i>count){
                    break;
                }
                sq_h=QString("UPDATE outh_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_h[i]).arg(Id);
                query.exec(sq_h);
                sq_p=QString("UPDATE outp_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_p[i]).arg(Id);
                query.exec(sq_p);
            }
        }
        if(model == 6){
            for (int i=601;i<=900;i++) {
                // outh_1 outp_1
                if(i>count){
                    break;
                }
                sq_h=QString("UPDATE outh_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_h[i]).arg(Id);
                query.exec(sq_h);
                sq_p=QString("UPDATE outp_%1 SET `%2`=%3 WHERE Id=%4").arg(dataSheet).arg(i-0).arg(data_p[i]).arg(Id);
                query.exec(sq_p);
            }
        }
        // 给线程断开连接
        QString connection;
        connection = db.connectionName();
        db.close();
        db = QSqlDatabase();
        db.removeDatabase(connection);
    }
    int Id;
    QString sq_h;
    QString sq_p;
    QSqlDatabase db;
    QSqlQuery query;
    double data_p[1000];
    double data_h[1000];
    int count;
    QString dataSheet;
    int model;
    int model_count;
 public:
    // 902,从一开始的话就是901,1为信息位置,记录数组个数
    myThread_1(double num_p[902],double num_h[902],int Id,QString dataSheet,int model){
        for(int i=1;i<=900;i++){
            this->data_p[i] = num_p[i];
            this->data_h[i] = num_h[i];
        }
        this->Id = Id;
        this->count = num_h[901];
        this->dataSheet = dataSheet;
        this->model = model;
        this->model_count = 1;
    }

};

下面是怎么把五千多列的数据分割成900一组的,

	// 这个是让线程知道,哪个数组是满的,哪个不是满的,多的1,2位都是我留的信息位,就不用再创建变量记录了
    int counthh = 1;
    for (int i=1;i<=10;i++) {
        if((73*73 - 900*(i-1))>=900){
            num_h[i][901] = 900;
        }else{
            num_h[i][901] = 73*73 - 900*(i-1);
        }

    }

	// 下面就是分数据的
    for (int i=1;i<=73*73;i++) {
        // outh_1 outp_1
        if(i<=900){
            num_h[1][i] = matrix1_h[i];
            num_p[1][i] = matrix1_p[i];
        }
        // outh_2 outp_2
        if((i>900)&&(i<=1800)){
            num_h[2][i-900] = matrix1_h[i];
            num_p[2][i-900] = matrix1_p[i];

        }
        // outh_3 outp_3
        if((i>1800)&&(i<=2700)){
            num_h[3][i-1800] = matrix1_h[i];
            num_p[3][i-1800] = matrix1_p[i];
        }
        // outh_4 outp_4
        if((i>2700)&&(i<=3600)){
            num_h[4][i-2700] = matrix1_h[i];
            num_p[4][i-2700] = matrix1_p[i];
        }
        // outh_5 outp_5
        if((i>3600)&&(i<=4500)){
            num_h[5][i-3600] = matrix1_h[i];
            num_p[5][i-3600] = matrix1_p[i];
        }
        // outh_6 outp_6
        if((i>4500)&&(i<=5400)){
            num_h[6][i-4500] = matrix1_h[i];
            num_p[6][i-4500] = matrix1_p[i];
        }
        // outh_7 outp_7
        if((i>5400)&&(i<=6300)){
            num_h[7][i-5400] = matrix1_h[i];
            num_p[7][i-5400] = matrix1_p[i];
        }
        // outh_8 outp_8
        if((i>6300)&&(i<=7200)){
            num_h[8][i-6300] = matrix1_h[i];
            num_p[8][i-6300] = matrix1_p[i];
        }
        // outh_9 outp_9
        if((i>7200)&&(i<=8100)){
            num_h[9][i-7200] = matrix1_h[i];
            num_p[9][i-7200] = matrix1_p[i];
        }
        // outh_10 outp_10
        if((i>8100)&&(i<=9000)){
            num_h[10][i-8100] = matrix1_h[i];
            num_p[10][i-8100] = matrix1_p[i];
        }
    }

这个完事后就是调用了,就是一次10个,一次20个,一次30个都放这了,当然哈,这个肯定是跑不满的,因为有好多表都是空的,线程进去就出来了,

    pool.setMaxThreadCount(20);
//    int expiryTimeout()线程长时间未使用将会自动退出节约资源,此函数返回等待时间。默认值30000ms,-1为不销毁
    pool.setExpiryTimeout(5000);
    // 多线程存储h,p表数据
//    pool.start(new myThread_1(num_p[1],num_h[1],Id,"1",1));
//    pool.start(new myThread_1(num_p[2],num_h[2],Id,"2",1));
//    pool.start(new myThread_1(num_p[3],num_h[3],Id,"3",1));
//    pool.start(new myThread_1(num_p[4],num_h[4],Id,"4",1));
//    pool.start(new myThread_1(num_p[5],num_h[5],Id,"5",1));
//    pool.start(new myThread_1(num_p[6],num_h[6],Id,"6",1));
//    pool.start(new myThread_1(num_p[7],num_h[7],Id,"7",1));
//    pool.start(new myThread_1(num_p[8],num_h[8],Id,"8",1));
//    pool.start(new myThread_1(num_p[9],num_h[9],Id,"9",1));
//    pool.start(new myThread_1(num_p[1],num_h[1],Id,"10",1));

//    pool.start(new myThread_1(num_p[1],num_h[1],Id,"1",2));
//    pool.start(new myThread_1(num_p[2],num_h[2],Id,"2",2));
//    pool.start(new myThread_1(num_p[3],num_h[3],Id,"3",2));
//    pool.start(new myThread_1(num_p[4],num_h[4],Id,"4",2));
//    pool.start(new myThread_1(num_p[5],num_h[5],Id,"5",2));
//    pool.start(new myThread_1(num_p[6],num_h[6],Id,"6",2));
//    pool.start(new myThread_1(num_p[7],num_h[7],Id,"7",2));
//    pool.start(new myThread_1(num_p[8],num_h[8],Id,"8",2));
//    pool.start(new myThread_1(num_p[9],num_h[9],Id,"9",2));
//    pool.start(new myThread_1(num_p[1],num_h[1],Id,"10",2));

//    pool.start(new myThread_1(num_p[1],num_h[1],Id,"1",3));
//    pool.start(new myThread_1(num_p[2],num_h[2],Id,"2",3));
//    pool.start(new myThread_1(num_p[3],num_h[3],Id,"3",3));
//    pool.start(new myThread_1(num_p[4],num_h[4],Id,"4",3));
//    pool.start(new myThread_1(num_p[5],num_h[5],Id,"5",3));
//    pool.start(new myThread_1(num_p[6],num_h[6],Id,"6",3));
//    pool.start(new myThread_1(num_p[7],num_h[7],Id,"7",3));
//    pool.start(new myThread_1(num_p[8],num_h[8],Id,"8",3));
//    pool.start(new myThread_1(num_p[9],num_h[9],Id,"9",3));
//    pool.start(new myThread_1(num_p[1],num_h[1],Id,"10",3));
	
	// 456表示三个线程合作一张表
    pool.start(new myThread_1(num_p[1],num_h[1],Id,"1",4));
    pool.start(new myThread_1(num_p[2],num_h[2],Id,"2",4));
    pool.start(new myThread_1(num_p[3],num_h[3],Id,"3",4));
    pool.start(new myThread_1(num_p[4],num_h[4],Id,"4",4));
    pool.start(new myThread_1(num_p[5],num_h[5],Id,"5",4));
    pool.start(new myThread_1(num_p[6],num_h[6],Id,"6",4));
    pool.start(new myThread_1(num_p[7],num_h[7],Id,"7",4));
    pool.start(new myThread_1(num_p[8],num_h[8],Id,"8",4));
    pool.start(new myThread_1(num_p[9],num_h[9],Id,"9",4));
    pool.start(new myThread_1(num_p[1],num_h[1],Id,"10",4));

    pool.start(new myThread_1(num_p[1],num_h[1],Id,"1",5));
    pool.start(new myThread_1(num_p[2],num_h[2],Id,"2",5));
    pool.start(new myThread_1(num_p[3],num_h[3],Id,"3",5));
    pool.start(new myThread_1(num_p[4],num_h[4],Id,"4",5));
    pool.start(new myThread_1(num_p[5],num_h[5],Id,"5",5));
    pool.start(new myThread_1(num_p[6],num_h[6],Id,"6",5));
    pool.start(new myThread_1(num_p[7],num_h[7],Id,"7",5));
    pool.start(new myThread_1(num_p[8],num_h[8],Id,"8",5));
    pool.start(new myThread_1(num_p[9],num_h[9],Id,"9",5));
    pool.start(new myThread_1(num_p[1],num_h[1],Id,"10",5));

    pool.start(new myThread_1(num_p[1],num_h[1],Id,"1",6));
    pool.start(new myThread_1(num_p[2],num_h[2],Id,"2",6));
    pool.start(new myThread_1(num_p[3],num_h[3],Id,"3",6));
    pool.start(new myThread_1(num_p[4],num_h[4],Id,"4",6));
    pool.start(new myThread_1(num_p[5],num_h[5],Id,"5",6));
    pool.start(new myThread_1(num_p[6],num_h[6],Id,"6",6));
    pool.start(new myThread_1(num_p[7],num_h[7],Id,"7",6));
    pool.start(new myThread_1(num_p[8],num_h[8],Id,"8",6));
    pool.start(new myThread_1(num_p[9],num_h[9],Id,"9",6));
    pool.start(new myThread_1(num_p[1],num_h[1],Id,"10",6));


    pool.waitForDone();

代码写的这一组,我测试的基本都在两秒多,提升明显
qt sqlite3 多线程 qt多线程数据库_mysql_04