赞
踩
QSqlDatabase类
如下代码:
- //! testMYSQLs
- void MainWindow::on_testMYSQL_clicked()
- {
-
- QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "localhost@3306");
- db.setHostName("localhost"); //数据库主机名
- db.setDatabaseName("databasex"); //数据库名
- db.setUserName("root"); //数据库用户名
- db.setPassword("123456"); //数据库密码
- bool bisOpenn = db.open(); //打开数据库连接
- qDebug()<<"bisOpenn="<<bisOpenn;
- //db.close(); //释放数据库连接
- }
此时出现如下错误:
- QSqlDatabase: QMYSQL driver not loaded
- QSqlDatabase: available drivers: QSQLITE QODBC3 QODBC QPSQL7 QPSQL
- bisOpenn= false
下面是对此问题的解决:
用qt打开 C:\Qt\4.8.5\src\plugins\sqldrivers\mysql\mysql.pro 工程,在此工程中链接 C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib\libmysql.lib 库及对应的MYSQL的头文件,具体PRO代码如下 :备注:我在工程中是把 MySQL 相关文件放在桌面的 mysqlinclude 文件夹下面,原因是我的MYSQL安装路径:C:\Program Files (x86)\MySQL\MySQL Server 5.5\include\ 里面有空格,不能有空格 ,故 mysql.pro 内容如下:
- TARGET = qsqlmysql
-
- SOURCES = main.cpp
- include(../../../sql/drivers/mysql/qsql_mysql.pri)
-
- include(../qsqldriverbase.pri)
-
- win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../../../mysqlinclude/lib/ -llibmysql
- else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../../../mysqlinclude/lib/ -llibmysql
-
- INCLUDEPATH += $$PWD/../../../../../mysqlinclude
- DEPENDPATH += $$PWD/../../../../../mysqlinclude
QMAKE,编译,生成,如下图所示: -- 网上很多人都用的QMAKE之类的,在这里,其实用QT工程来编译,是最好最快最方便的一种办法 如下图所示:
生成好后,把生成好的输入COPY至 C:\Qt\4.8.5\plugins\sqldrivers 下面,即可。如下图所示:
接下来我就开始 写代码,代码如下:
- //! testMYSQLs
- void MainWindow::on_testMYSQL_clicked()
- {
- QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "localhost@3306");
- db.setHostName("localhost"); //数据库主机名
- db.setPort(3306);
-
- db.setDatabaseName("xdatabase"); //数据库名
- db.setUserName("root"); //数据库用户名
- db.setPassword("123456"); //数据库密码
- bool bisOpenn = db.open(); //打开数据库连接
- //db.close();
- if(bisOpenn==true)
- {
- QSqlQuery query;
- query.exec("create table test_student(id INTEGER PRIMARY KEY autoincrement,name nvarchar(20), age int)"); //id自动增加
- query.exec("insert into test_student values(1,'小明', 14)");
- query.exec("insert into student values(2,'小王',15)");
- }
- //qDebug()<<"bisOpenn="<<bisOpenn;
- db.close(); //释放数据库连接
- }
结果报错信息如下:
- F:\zip\testCode\debug\testCode.exe 启动中...
- [wificommon]开始进入....QSqlQuery::exec: database not open
- QSqlQuery::exec: database not open
- QSqlQuery::exec: database not open
解决如下:
原因:QSqlQuery 没有与 db 数据库联系起来,正确代码如下:
- bool MainWindow::initDataBase()
- {
- m_db = QSqlDatabase::addDatabase("QMYSQL", "localhost@3306");
- m_db.setHostName("localhost"); //数据库主机名
- m_db.setPort(3306);
-
- m_db.setDatabaseName("ljtdatabase"); //数据库名
- m_db.setUserName("root"); //数据库用户名
- m_db.setPassword("123456"); //数据库密码
- //bool bisOpenn = db.open(); //打开数据库连接
- m_bisOpenn = m_db.open(); //打开数据库连接
- return m_bisOpenn;
- }
-
- MainWindow::~MainWindow()
- {
- m_db.close();
- delete ui;
- }
- void MainWindow::createTable()
- {
- QSqlQuery query(m_db);
- QString ssql = "CREATE TABLE test_table2(id int(11) NOT NULL,Name varchar(255) DEFAULT NULL, age int(3) DEFAULT NULL,PRIMARY KEY (id)) ;";
- query.exec(ssql);
- }
上面为创建表的代码,结果如下:
下面为对SQL进行操作的一些代码及结果说明:
代码如下:
- //! SELECT * FROM test_table2
- void MainWindow::queryResTable()
- {
- QSqlQuery query(m_db);
- QString sel = "SELECT * FROM test_table2";
- query.exec(sel);
- while (query.next()) {
- qDebug()<<query.size()<<query.value(0).toInt()<<" "<<query.value(1).toString()<<" "<<query.value(2).toInt();
- }
- }
-
- //! testMYSQLs
- void MainWindow::on_testMYSQL_clicked()
- {
- if(m_bisOpenn==false) return;
- queryResTable();
- }
执行结果:
- [wificommon]开始进入....
- 4 1 "Name1" 10
- 4 2 "Name2" 20
- 4 3 "Name3" 30
- 4 4 "Name4" 40
同样的情况,代码如下:
- //! SELECT * FROM test_table2
- void MainWindow::queryResTable()
- {
- QSqlQuery query(m_db);
- QString sel = "SELECT * FROM test_table2";
- query.exec(sel);
-
- int fieldNo = query.record().indexOf("age");
- int fieldName = query.record().indexOf("Name");
- while (query.next()) {
- int country = query.value(fieldNo).toInt();
- QString sName = query.value(fieldName).toString();
- qDebug()<<country<<" "<<sName;
- }
- }
结果如下:
- 10 "Name1"
- 20 "Name2"
- 30 "Name3"
- 40 "Name4"
下面给表INSERT数据:代码如下:
- void MainWindow::bindValue1()
- {
- QSqlQuery query(m_db);
- query.prepare("INSERT INTO test_table2 (id, Name, age) "
- "VALUES (:id, :Name, :age)");
- query.bindValue(":id", 5);
- query.bindValue(":Name", "Name5");
- query.bindValue(":age", 50);
- query.exec();
- }
图:
另一种方法:
- void MainWindow::bindValue2()
- {
- QSqlQuery query(m_db);
- query.prepare("INSERT INTO test_table2 (id, Name, age) "
- "VALUES (:id, :Name, :age)");
- query.bindValue(0, 6);
- query.bindValue(1, "Name6");
- query.bindValue(2, 60);
- query.exec();
- }
另外一种方法:
- void MainWindow::bindValue3()
- {
- QSqlQuery query(m_db);
- query.prepare("INSERT INTO test_table2 (id, Name, age) "
- "VALUES (?, ?, ?)");
- query.bindValue(0, 7);
- query.bindValue(1, "Name7");
- query.bindValue(2, 70);
- query.exec();
- }
图:
另外一种方法:
- void MainWindow::bindValue4()
- {
- QSqlQuery query(m_db);
- query.prepare("INSERT INTO test_table2 (id, Name, age) "
- "VALUES (?, ?, ?)");
- query.addBindValue(8);
- query.addBindValue("Name8");
- query.addBindValue(80);
- query.exec();
- }
图:
下面是对存储过程的一个处理: ---- 没有验证
- // AsciiToInt() -- 是一个存储过程,可以把它的输入输出参数带回来
- void MainWindow::bindValue5()
- {
- QSqlQuery query(m_db);
- query.prepare("CALL AsciiToInt(?, ?)");
- query.bindValue(0, "A");
- query.bindValue(1, 0, QSql::Out);
- query.exec();
- int i = query.boundValue(1).toInt(); // i is 65
- }
下面这个是验证过的:创建语句
- create procedure qtestproc (OUT param1 INT, OUT param2 INT)
- BEGIN
- set param1 = 42;
- set param2 = 43;
- END
代码语句:
- void MainWindow::bindValue5()
- {
- // QSqlQuery query(m_db);
- // query.prepare("CALL AsciiToInt(?, ?)");
- // query.bindValue(0, "A");
- // query.bindValue(1, 0, QSql::Out);
- // query.exec();
- // int i = query.boundValue(1).toInt(); // i is 65
- // qDebug()<<"i="<<i;
-
- QSqlQuery q(m_db);
- q.exec("call qtestproc (@outval1, @outval2)");
- q.exec("select @outval1, @outval2");
- q.next();
- qDebug() << q.value(0) << q.value(1); // outputs "42" and "43"
- }
执行结果:
[wificommon]开始进入....QVariant(qlonglong, 42) QVariant(qlonglong, 43)
- void MainWindow::insertValue()
- {
- QSqlQuery query(m_db);
- query.exec("INSERT INTO test_table2 (id, Name, age) "
- "VALUES (9, 'Name9', 90)");
- query.exec();
- }
- void MainWindow::insertValue2()
- {
- QSqlQuery q(m_db);
- q.prepare("insert into test_table2 values (?, ?, ?)");
-
- QVariantList ints1;
- ints1 << 10 << 11 << 12 << 13;
- q.addBindValue(ints1);
-
- QVariantList names;
- names << "Name10" << QVariant(QVariant::String) << "Name12" << QVariant(QVariant::String);
- q.addBindValue(names);
-
- QVariantList ints2;
- ints2 << 100 << 110 << 120 << 130;
- q.addBindValue(ints2);
-
- if (!q.execBatch())
- qDebug() << q.lastError();
- }
图:
对事务操作:因为不支持,所以没法进行校验,如果哪种数据库支持,可以校验一下
- void MainWindow::transaction()
- {
- if (QSqlDatabase::database().driver()->hasFeature(QSqlDriver::Transactions))
- {
- QSqlDatabase::database().transaction();
- QSqlQuery query(m_db);
- query.exec("SELECT id FROM test_table2 WHERE age=30");
- if (query.next())
- {
- query.exec("UPDATE test_table2 SET Name = \"tx\" ");
- //query.exec("UPDATE test_table2 SET Name = \"tx\" WHERE id = 4 ");
- }
- QSqlDatabase::database().commit();
- }
- }
关于MYSQL的重连,在 void QSqlDatabase::setConnectOptions ( const QString & options = QString() ) 中有一个选项 MYSQL_OPT_RECONNECT ,还可以参考 http://stackoverflow.com/questions/6984804/mysql-reconnect-c 大体意思就是,新建一个线程,每隔1S监视数据库的情况,如果断开 ,则进行重连,然后新线程和旧线程之间通信。或者看源码介绍:https://bugreports.qt.io/browse/QTBUG-4510 https://dev.mysql.com/doc/search/?d=12&p=1&q=MYSQL_OPT_RECONNECT
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。