QSqlDatabase类学习笔记

http://blog.csdn.net/Lutx/article/details/7262123
http://blog.csdn.net/reborntercel/article/details/6991147


 #include <QtSql>
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="<<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)


下面是insert值:

    void MainWindow::insertValue()
    {
        QSqlQuery query(m_db);
        query.exec("INSERT INTO test_table2 (id, Name, age) "
                   "VALUES (9, 'Name9', 90)");
        query.exec();
    }

 

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

图:


对事务操作:因为不支持,所以没法进行校验,如果哪种数据库支持,可以校验一下

    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


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值