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="<
此时出现如下错误:
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="<
结果报错信息如下:
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()<
执行结果:
[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()<
结果如下:
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="<
执行结果:
[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