Qt使用ODBC连接MySQL数据库

发布于:2025-06-14 ⋅ 阅读:(20) ⋅ 点赞:(0)

Qt使用ODBC连接MySQL数据库

本文基于QT5.14.2和mysql8.0.40.0使用odbc-9.1.0-winx64连接起来

重要提示:MySQL、Qt、Connector/ODBC最好都选择相同的位数,本人熬夜到凌晨都没有搞定此连接,最后才发现是位数不同,这是大坑,各位避开,本文章以选择64位为例。

一、 先安装mysql数据库

1. 下载位置:

mysql官网
我用的是mysql-installer-community-8.0.40.0,软件链接放这里:百度网盘

2. 安装过程

安装时,选择全部安装,把安装时填的密码记下来。
之前如果有旧的软件包,一定要卸载干净再安装。
安装好后,在命令行中输入:mysql -h localhost -u root -p
然后输入刚才填的密码,如果出现以下窗口,表示安装登录成功。
在这里插入图片描述

二、安装Connector/ODBC连接工具。

1. 下载位置:

mysql官网
我用的是mysql-connector-odbc-9.1.0-winx64,软件链接放这里:百度网盘

2. 安装过程

安装时选择完全安装即可。
安装完成后进行配置:
控制面板->管理工具->ODBC数据源(64位)
->添加->MySQL ODBC 9.1 Unicode Driver(版本9.1.0)

在这里插入图片描述
点添加
出来这个窗口
在这里插入图片描述
选择MySQL ODBC 9.1 Unicode Driver
点完成
出来这个
在这里插入图片描述
点击Test, 如果连接成功会弹出

在这里插入图片描述

点击确定,安装成功

三、安装QT

1. 下载位置:

清华大学镜像
我用的是qt-opensource-windows-x86-5.14.2,软件链接放这里:百度网盘

2. 安装过程

安装时要选择MinGW 64位编译器

四、连接数据库

在.pro工程文件添加sql模块
database.pro文件如下:

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

DEFINES += QT_DEPRECATED_WARNINGS



SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

五、使用数据库

以下为main.cpp文件:

#include "mainwindow.h"

#include <QApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlResult>
#include <QSqlRecord>
#include <QSqlTableModel> //可省
#include <QSqlQueryModel> //可省
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();
//1. 查询已有的数据库驱动
    QStringList sl = QSqlDatabase::drivers();
    int nSize = sl.size();
    for(int i =0; i<nSize; i++)
        qDebug()<<sl.at(i);
    //得到QSQLITE, QODBC, QODBC3, QPSQL, QPSQL7
    //SQLITE是一种轻量级的数据库,
    //ODBC是一种windows的连接方式,
    //程序的位数要和驱动位数匹配, 这里我们找不到Mysql的驱动

//2. 设置数据库的驱动程序,我们使用QODBC来连接
    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC"); //或者QODBC3
    //设置数据源名称
//    QString dsn = "Driver={MySQL ODBC 8.0 ANSI Driver};";//ANSI/Unicode
    QString dsn = "Driver={MySQL ODBC 9.1 Unicode Driver};";//ANSI/Unicode
    //dsn.append("DATABASE=testdb"); //如果不在连接时指定数据库, 那么就需要在后面执行"use testdb"语句来进入数据库
    db.setDatabaseName(dsn);
//    db.setDatabaseName("mysqlOdbc");

    //设置连接数据库的主机和用户
    db.setHostName("localhost");
    db.setPort(3306);
    db.setUserName("root");
    db.setPassword("123456");

    //调用open连接数据库
    bool ret = db.open();
    if(ret == false)
    {
        qDebug()<<"connect err:"<<db.lastError().text();
        return 0;
    }
    qDebug()<<"connect ok\n";

    //执行Sql语句时使用
    QSqlQuery query(db);
    QString sql;
//设置字符集? 可选

//3. 创建数据库
    sql = "create database testDB";
    ret = query.exec(sql);
    if(ret == false)
    {
        //将错误码转换为数字
        int err = query.lastError().nativeErrorCode().toInt();
        if(err != 1007 )//1007数据库已存在
            qDebug()<<"create DB err"<<query.lastError().text();
    }

//4. 如果之前没有指定连接的数据库,那么在之后就需要选择使用的数据库
    sql = "use testdb";
    ret = query.exec(sql);
    if(ret == false)
    {
        qDebug()<<"use testdb err:"<<query.lastError().text();
    }

//5.创建表
    QString qtn("student");
    sql = QString("create table %1("
                  "stu_id int primary key,"
                  "name varchar(20),"
                  "sex varchar(12),"
                  "birth date,"
                  "salary float,"
                  "address varchar(50))").arg(qtn);
    ret = query.exec(sql);
    if(ret == false)
    {
         int err = query.lastError().nativeErrorCode().toInt();
         if(err != 1050)//1050代表表已经存在
         {
             qDebug()<<"create table err:"<<query.lastError().text();
         }
    }

//6. 在数据库表中插入记录
    sql = QString("insert into %1 values"
        "(101,'张大','男','1978-5-8',5000.00,'北京市海淀区'),"
        "(102,'张二','男','1986-6-9',4500.00,'西安市莲湖区'),"
        "(103,'张三','女','1990-2-2',6000.00,'西安市碑林区')"
                  ).arg(qtn);

    ret = query.exec(sql);
    if(ret == false)
    {
        int err = query.lastError().nativeErrorCode().toInt();
        if(err != 1062) //1062,主键重复, 代表已经插过记录
        {
            qDebug()<<"insert row err"<<query.lastError().text();
        }
    }

//7. 获取表的记录数和字段数
    QSqlTableModel * pTm = new QSqlTableModel(nullptr,db);

    pTm->setTable(qtn);
    pTm->select();

    int nRow = pTm->rowCount();//通过表模型获取记录个数

    QSqlRecord rec = pTm->record();//获取记录
    int nField = rec.count();//通过记录获取字段数

 //8. 从数据库中查询
    sql = QString("select * from %1").arg(qtn);
    ret = query.exec(sql);
    //nField = query.record().count();
	QString str;

//  str= query.record().fieldName(1);  //获取字段名称
//  qDebug()<<"str field:"<<str;

    while(query.next())
    {
        //取出每个字段的值
		for(int i = 0; i< nField; i++)
        {
            str += query.value(i).toString();
            str += " ";
        }
        sl<<str;
        str.clear();
    }
	for(int j = 0; j<sl.size(); j++)
    {
        qDebug()<<sl[j];
    }

//9 清理工作
    db.close();
    delete pTm;

    //sql = "select database()"; //如何取出这个结果?
    //query.exec(sql);
	
    return a.exec();
}

如果能输出以下内容,证明成功连接,并可正常使用

"QSQLITE"
"QODBC"
"QODBC3"
"QPSQL"
"QPSQL7"
connect ok

"QSQLITE"
"QODBC"
"QODBC3"
"QPSQL"
"QPSQL7"
"101 张大 男 1978-05-08 5000 北京市海淀区 "
"102 张二 男 1986-06-09 4500 西安市莲湖区 "
"103 张三 女 1990-02-02 6000 西安市碑林区 "