Qt+MySql开发笔记:Qt5.9.3的mingw32版本编译MySql8版本驱动并Demo连接数据库测试

Posted 长沙红胖子Qt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt+MySql开发笔记:Qt5.9.3的mingw32版本编译MySql8版本驱动并Demo连接数据库测试相关的知识,希望对你有一定的参考价值。

若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/129687210

红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…

Qt开发专栏:三方库开发技术


前言

  之前特定的mysql版本msvc版本已经调通了,但是为了更好的跨平台,所以选择用mingw32版本,于是需要编译mysql驱动的mingw32版本的驱动库,以便提供给qt连接mysql使用。


编译环境

Qt5.9.3 mingw32

  安装得时候记得要勾选上源码

mysql-installer-community-8.0.16.0

  

下载数据库

  https://downloads.mysql.com/archives/community/
  


编译mysql驱动库(Qt5.9.3+mysql8.0.16)

步骤一:安装Qt5.9.3勾选mingw32版本。

  
  其他过程略。

步骤二:下载数据库32位驱动运行程序并解压

  下载数据库运行包文件。(注意:这里要注意跟目标机器安装的版本要一致)。
  下载地址:https://downloads.mysql.com/archives/c-c
  
  

步骤三:打开qt中自带的mysql源码工程

  
  使用QtCreator打开:
  
  注意工程的编译套件。(注意:shadow build在这里不管作用,最后是生成到根目录上去了,跟pro包含的pri配置有关
  
  
  

步骤四:qmake并且build构建

  构建成功:
  
  这里生成到磁盘根目录下去了:
  
  

步骤五:替换插件的mysql库

  

步骤六:将数据库的libmysql.dll拷贝到bin目录

  这个文件是运行库,也是需要自动手动额外copy和打包时额外拷贝的,具体看 “入坑一”。
  需要将下载下来mysql的lib下的libmysql.dll拷贝到qt的gcc的bin目录下,而且打包软件的时候也要带上。
  
  如果是打包,则windeployqt不会主动拷贝,也需要手动复制过去:
  

步骤七:编译应用连接测试

  编译数据库的工程:
  
  Ok了,提示不再是缺少驱动了。
  下面配置好数据库,再尝试:
  

步骤八:配置数据库账号允许远程操作

  这是因为账号不被允许远程登录,所以需要修改数据库用户的配置,让其允许远程登录。
  修改用户被允许远程登录,先使用mysql控制端输入密码登录,然后操作:

use mysql;
select host,host from user;
update user set host = ‘%’ where user = ‘root’;
select host,host from user;

  这时候,还是不行,需要强行刷新以下

flush privileges;

  

  

  然后成功:
  
  至此,Qt5.9.3 mingw32 + mysql8.0.16数据库完成。

步骤九:数据库的远程操作工具连接

  使用远程工具测试,发现出错:
  

  这是因为8.0之后mysql更改了密码的加密规则,目前的客户端连接软件还不支持Mysql8新增加的加密方式caching_sha2_password,所以需要修改用户的加密方式,将其改回旧加密验证方式。
  先登录mysql命令行,执行以下,主要是youPassword要替换为你使用远程登录的账户密码:

alter user 'root'@'%' identified by 'youPassword' password expire never;
alter user root identified with mysql_native_password by 'youPassword';
flush privileges;

  
  


入坑

入坑一:开始连通后打包后不行了,回头也不行了

问题

  开始连通后打包后不行了,回头也不行了

原因

  需要使用到libmysql.dll运行库

解决

  需要将下载下来mysql的lib下的libmysql.dll拷贝到qt的gcc的bin目录下,而且打包软件的时候也要带上。
  

  如果是打包,则windeployqt不会主动拷贝,也需要手动复制过去:
  


若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/129687210

树莓派开发笔记(十七):树莓派4B+上Qt多用户连接操作Mysql数据库同步(单条数据悲观锁)

前言

  安装了mysq数据库,最终时为了实现在一个树莓派上实现多用户多进程操作的同步问题,避免数据并发出现一些错误,本篇安装了远程服务并且讲述了使用Qt进行悲观锁for update操作,命令行进行同步查询的示例。

<br>

其他操作

  这里只是稍微提一下,具体参照博主的树莓派系列博客,非常详细。
  远程登陆界面

sudo apt-get install tightvncserver
sudo apt-get install xrdp
sudo service xrdp restart
sudo ufw allow 3389
sudo service ufw restart

  然后可以使用window远程桌面登陆了:
  默认用户名:pi
  默认密码:raspberry
  
  

安装qt5

sudo apt-get install qt5-default
sudo apt-get install qtcreator

  安装好后,远程桌面的程序里面就多了个qtcreator了:
  
  
  创建一个界面工程,然后运行:
  (编译速度比几年前的3B+快一些,后续开发过程中测试一下,是否可以忽略3B+的交叉编译)
  
  检查数据库驱动:
  
  没有mysql的数据库驱动。

sudo apt-get install libqt5sql5-mysql

  

<br>

Qt操作mariadb数据库

QSqlDatabase db;
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setPort(3306);
db.setDatabaseName("data");
db.setUserName("root");
db.setPassword("a1234567");

if(db.open())

    LOG << "Succeed to open db";
else
    LOG << "Failed to open db:" << db.lastError().text();
    return;


QString cmd = "select * from student;";
QSqlQuery query = db.exec(cmd);
while(query.next())

    LOG << query.value(0).toString()
        << query.value(1).toString()
        << query.value(2).toString()
        << query.value(3).toString();

  

<br>

多用户操作

  本意是为了多用户操作,那么读的时候需要加读锁,写的时候需要加写锁。
  两个用户同时读取了数据库中的一条记录,此时用户A对其中一个字段的值进行了修改操作并进行了提交,后来用户B也对这个字段进行了修改,用户B的提交将会覆盖用户A提交的值。
  

锁类型

悲观锁

  每次去取数据,很悲观,都觉得会被别人修改,所以在拿数据的时候都会上锁。简言之,共享资源每次都只给一个线程使用,其他线程阻塞,等第一个线程用完后再把资源转让给其他线程。synchronized和ReentranLock等都是悲观锁思想的体现。

乐观锁

  每次去取数据,都很乐观,觉得不会被被人修改。因此每次都不上锁,但是在更新的时候,就会看别人有没有在这期间去更新这个数据,如果有更新就重新获取,再进行判断,一直循环,直到拿到没有被修改过的数据。(mysql需要自己实现乐观锁)。

for update使用场景(悲观锁)

  for update 可以为数据库中的一行数据加上一个排它锁。当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。
  如果项目对某个数据准确性有要求,并且项目存在并发(不一定高并发),则需要使用 for update。
  比如:用户A使用余额购买商品,此时用户B向用户A发起转账,如果恰好处在同一时间,则可能造成用户A最终余额错误。此时需要使用 for update 进行数据加锁防止出错。
  这种情况下,即使并发很小,但是也会有一定的概率会碰到,而余额的错误即使差一分钱也是不能容忍的,所以这种特定的场景,即使不是高并发,也应该使用 for update 规避问题。

for update 用法

begin;
select * from XXX where XXX for update;
...
commit;

  for update 必须在事务中才生效。

<br>

Qt测试

使用127.0.0.1的ip进行连接(本地连接)

QSqlDatabase db;
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setPort(3306);
db.setDatabaseName("data");
db.setUserName("root");
db.setPassword("a1234567");

if(db.open())

    LOG << "Succeed to open db";
else
    LOG << "Failed to open db:" << db.lastError().text();
    return;


if(db.transaction())

    QString cmd = "select * from student for update;";
    QSqlQuery query = db.exec(cmd);
    while(query.next())
    
        LOG << query.value(0).toString()
            << query.value(1).toString()
            << query.value(2).toString()
            << query.value(3).toString();
    
    for(int index = 0; index < 10; index++)
    
        QThread::sleep(1);
        LOG << "sleep:" << index;
    
    if(!db.commit())
    
        LOG << "Failed to commit";
    

  
  至此,我们的锁加入成功,说清楚原理可以方便大家着手开始开发多用户进程操作数据库的同步开发了。

使用局域网的ip进行连接(远程连接)

QSqlDatabase db;
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("192.168.0.103");
db.setPort(3306);
db.setDatabaseName("data");
db.setUserName("root");
db.setPassword("a1234567");

if(db.open())

    LOG << "Succeed to open db";
else
    LOG << "Failed to open db:" << db.lastError().text();
    return;


if(db.transaction())

    QString cmd = "select * from student for update;";
    QSqlQuery query = db.exec(cmd);
    while(query.next())
    
        LOG << query.value(0).toString()
            << query.value(1).toString()
            << query.value(2).toString()
            << query.value(3).toString();
    
    for(int index = 0; index < 10; index++)
    
        QThread::sleep(1);
        LOG << "sleep:" << index;
    
    if(!db.commit())
    
        LOG << "Failed to commit";
    

  连接不上:
  
  这个时候需要修改下配置:

sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

  

  重启服务:

systemctl restart mysql.service

  
  继续测试,下面是用树莓派使用局域网ip(之前也不能连接127.0.0.1):
  
  连接成功,然后在局域网pc上连接,但是不能打开事务:
  
  修改一下:
  

  这个其实是跟mysql驱动有关系,因为笔者是几年前弄得libmysql.dll和libmysqld.dll,这个不深究了,已经可以远程操作了。

以上是关于Qt+MySql开发笔记:Qt5.9.3的mingw32版本编译MySql8版本驱动并Demo连接数据库测试的主要内容,如果未能解决你的问题,请参考以下文章

编译QT错误

Qt图形视图体系结构

Qt编译目录下exe文件执行报错问题的解决办法

Qt 5.9.3 如何静态编译和部署?

树莓派开发笔记(十七):树莓派4B+上Qt多用户连接操作Mysql数据库同步(单条数据悲观锁)

树莓派开发笔记(十七):树莓派4B+上Qt多用户连接操作Mysql数据库同步(单条数据悲观锁)