Essential Qt 第二十章 数据库

来源:互联网 发布:unity3d控制物体跳跃 编辑:程序博客网 时间:2024/05/17 07:37

                 对于编程而已,数据库操作是一个非常常见的内容,Qt提供了目前主流数据库的支持,这一章将以sqlite3为例,演示下Qt与数据库相关的基本内容,另外这里加速读者已经熟悉sqlite3的操作已经数据库语言。

                 以sqlite3为例,如果需要操作数据库的内容,基本的操作可以分成两个部分,第一连接数据库,第二操作数据库(如使用SELECT语句查询内容),针对这两个步骤,Qt通过使用QSqlDatabase和QSqlQuery来完成操作

                 首先来看下QSqlDatabase类,这个类用于和数据库的连接,我们先看一个简单的连接

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(tr("/home/vim1024/QtTest/Database/PatientInfo.db"));if (!db.open())qDebug() << tr("数据库打开失败");
                QSqlDatabase通过静态函数addDatabase()来创建一个数据库连接的对象,该函数的参数是数据库对应的类型,例子里使用QSqlite3数据库,所以参数为QSQLITE3,Qt还提供了QMYSQL,QDB2等参数,函数会根据参数调用对应的数据库驱动文件,收授权许可的影响,Qt只能以源代码的形式提供数据库驱动,用户必须自己编译,不过幸运的是sqlite3数据库不在此列,这可以省去很多编译方便的麻烦.


                addDatabase()函数返回一个数据库连接(QSqlDatabase)对象 ,通过setDatabaseName()这个对象可以设置与具体数据库的连接,连接完成后通过open()函数可以判断是否连接成功,如果open()函数返回值为true就说明连接成功,这样就可以开始操作数据库了。这里有个地方需要注意,addDatabase()函数返回的虽然看上去是一个局部变量,但是在程序和数据库的连接一旦建立,在程序执行期间将一直保持连接状态,如需中断连接,必须调用QSqlDatabase::removeDatabase()函数来显示的中断,对于一个已经和数据库建立连接的程序来说,如果在其他地方还有类似

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(tr("F:/sql/PatientInfo.db"));
这样的代码,Qt就会法术类似这样的警告信息

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.

QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.


               上面的代码使用了qDebug()函数,使用这个函数需要包含头文件<QDebug>,这个类的作用类似于c++标准io的std::cout, 用于在命令行/控制台输出一些信息,qDebug()不但可以输出c++的数据,也可以输入各种Qt的类,比如前一章使用到的QRect类,这样的类的对象如果使用std::cout来输入值会非常麻烦,而使用qDebug()就会简单很多,比如有

QRect A(0,0,20,20);qDebug()<<A;
输出结果为:QRect(0,0 20x20);


               在建立了铜数据库的连接,接下来就是操作数据库了,最常见的就是各种SELECT语句了,Qt使用QSqlQuery对数据库进行操作。数据库的操作可以分成两个部分,发送请求,获取返回值。

QSqlQuery sqlQuery;QString sqlStr = tr("SELECT name,age,hasHistory,checkDate FROM PatientInfo;");sqlQuery.exec(sqlStr);  //执行SQl语句while (sqlQuery.next())  //获取返回值{QString names = sqlQuery.value(tr("name")).toString();QString age = sqlQuery.value(tr("age")).toInt();QString hasHistory = sqlQuery.value(tr("hasHistory")).toString();QString checkDate = sqlQuery.value(tr("checkDate")).toString();                qDebug()<<"姓名:"<<names<<"  年龄:"<<age<<"  有过往病史:"<<hasHistory<<"上次检查日期:"<<checkDate;}
             首先看发送请求,也就是执行sql语句,这个比较简单,使用QSqlQuery的exec()函数即可执行需要执行的语句,如果执行成功该函数会返回true,否则返回false,关于exec()函数有个特殊的地方,sqlite3在命令行模式下可以多条语句一起执行,但这里使用exec()来执行只能一条一条的执行,否则就会执行失败,函数返回false,这个特殊情况是针对sqlite3数据库的,如果使用其他数据库,可以把多条sql语句写在一个QString里然后调用exec()函数一次性执行

             略显麻烦的是获取返回值,大部分时间是查询的结果,QSqlquery每次执行完一个sql语句后,如果该语句会有返回值,可以调用value()来获得返回值,该函数有两个重置,参数分别为QString(列名)和int(列的索引)。但在使用value()函数之前必须先调用next()函数,来使得QSqlQuery对象来“跳转至”下一条,就是第一条结果,如果有下一条结果,那next()返回值为true,否则返回false;

            上面代码中查询了整张PatientInfo表,假设这张表总计有100行,使用exec()函数执行完查询语句后,得到的结果就有100行,如果想获得第一行的结果,拿先调用next()函数来使得QSqlQuery对象“指向”返回值的第一条,然后通过value()函数来制定列的值。需要注意的是每次执行一跳sql语句,如果该语句有查询结果,拿就会覆盖掉上一次查询的结果。


            对于数据库连接,很多时候需要连接多个数据库,上面说过对于一个数据库只需要连接一次即可,如果需要同时连接多个数据库,则需要使用QSqlDatabase::addDatabase()函数的第二个参数和QSqlQuery的构造函数的参数,从文档可以得知,这两个参数都是QString,也就是数据库的名字,

    QSqlDatabase::addDatabase("QSQLITE","CustomDB");  //使用第二个参数,将数据库命名为CustomDB    db.setDatabaseName(tr("F:/sql/PatientInfo.db"));    QSqlQuery sqlQuery("CustomDB");  //指定操作的数据库是CustomDB而不是默认数据库    QString sqlStr = tr("SELECT CardName , CardLevel FROM BuyCards;");    sqlQuery.exec(sqlStr);
          首先QSqlDatabase::addDatabase()函数的第二个参数具有默认值,如果不给参数,程序将会把这个链接设为默认链接,如果需要同时链接到其他数据库,就可以使用第二个参数------ 给新的数据库连接起个你认为好听的名字,以便和默认数据库连接想区分。然后通过QsqlQuery对象来操作数据库是,通过设定参数为“CustomDB”告诉程序,这次操作的数据库是"CustomDB"而不是默认数据库