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 西安市碑林区 "