QSqlDatabase类学习笔记

QSqlDatabase类学习笔记
参考
http://blog.csdn.net/Lutx/article/details/7262123
http://blog.csdn.net/reborntercel/article/details/6991147


 #include
QT += sql
QSqlDatabase类实现了数据库连接的操作
QSqlQuery类执行SQL语句
QSqlRecord类封装数据库所有记录

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 下面,即可。如下图所示:

QSqlDatabase类学习笔记_第1张图片

QSqlDatabase类学习笔记_第2张图片

接下来我就开始 写代码,代码如下:

//! 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);
}
上面为创建表的代码,结果如下:

QSqlDatabase类学习笔记_第3张图片

下面为对SQL进行操作的一些代码及结果说明:

QSqlDatabase类学习笔记_第4张图片

代码如下:

//! 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();
}
图: QSqlDatabase类学习笔记_第5张图片

另一种方法:

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();
}
QSqlDatabase类学习笔记_第6张图片

另外一种方法:

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();
}
图:

QSqlDatabase类学习笔记_第7张图片
另外一种方法:

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();
}
图:

QSqlDatabase类学习笔记_第8张图片

QSqlDatabase类学习笔记_第9张图片
下面是对存储过程的一个处理: ---- 没有验证

// 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) 

下面是insert值:

void MainWindow::insertValue()
{
    QSqlQuery query(m_db);
    query.exec("INSERT INTO test_table2 (id, Name, age) "
               "VALUES (9, 'Name9', 90)");
    query.exec();
}
QSqlDatabase类学习笔记_第10张图片

insert的另外一种方法:

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();
}
图:

QSqlDatabase类学习笔记_第11张图片
对事务操作:因为不支持,所以没法进行校验,如果哪种数据库支持,可以校验一下

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


你可能感兴趣的:(QSqlDatabase类学习笔记)