Qt 提供了 QtSql 模塊來提供平臺獨立的基於 SQL 的數據庫操做。這裏咱們所說的「平臺獨立」,既包括操做系統平臺,有包括各個數據庫平臺。另外,咱們強調了「基於 SQL」,由於 NoSQL 數據庫至今沒有一個通用查詢方法,因此不可能提供一種通用的 NoSQL 數據庫的操做。Qt 的數據庫操做還能夠很方便的與 model/view 架構進行整合。一般來講,咱們對數據庫的操做更多地在於對數據庫表的操做,而這正是 model/view 架構的長項。mysql
Qt 使用QSqlDatabase表示一個數據庫鏈接。更底層上,Qt 使用驅動(drivers)來與不一樣的數據庫 API 進行交互。Qt 桌面版本提供了以下幾種驅動:sql
驅動 數據庫數據庫
QDB2 IBM DB2 (7.1 或更新版本)服務器
QIBASE Borland InterBase架構
QMYSQL MySQL函數
QOCI Oracle Call Interface Driver測試
QODBC Open Database Connectivity (ODBC) – Microsoft SQL Server 及其它兼容 ODBC 的數據庫ui
QPSQL PostgreSQL (7.3 或更新版本)this
QSQLITE2 SQLite 2操作系統
QSQLITE SQLite 3
QSYMSQL 針對 Symbian 平臺的SQLite 3
QTDS Sybase Adaptive Server (自 Qt 4.7 起廢除)
不過,因爲受到協議的限制,Qt 開源版本並無提供上面全部驅動的二進制版本,而僅僅以源代碼的形式提供。一般,Qt 只默認搭載 QSqlite 驅動(這個驅動實際還包括 Sqlite 數據庫,也就是說,若是須要使用 Sqlite 的話,只須要該驅動便可)。咱們能夠選擇把這些驅動做爲 Qt 的一部分進行編譯,也能夠看成插件編譯。
在QT下使用數據庫必須在.pro文件中添加此模塊:QT +=sql
若是習慣於使用 SQL 語句,咱們能夠選擇QSqlQuery類;若是隻須要使用高層次的數據庫接口(不關心 SQL 語法),咱們能夠選擇使用QsqlTableModel類。
基本數據庫頭文件:
#include <QtSql/QSqlDatabase>
#include <QSqlError>
#include <QtSql/QSqlQuery>
在使用時,咱們能夠經過查詢qt支持的數據庫驅動:
qDebug()<<QSqlDatabase::drivers();
如:("QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7")
//添加數據庫
QSqlDatabase db=QSqlDatabase::addDatabase( "QMYSQL");
//鏈接數據庫
db.setHostName("localhost"); //數據庫服務器IP
//db.setHostName("127.0.0.1");
db.setUserName("root"); //數據庫用戶名
//db.setPassword("123456"); //密碼
db.setDatabaseName("stu"); //使用哪一個數據庫
//打開數據庫
if(!db.open())
{
qDebug()<<db.lastError();
return ;
}
重點:結果發現沒法打開數據庫。Qt沒法加載MYSQL. QtSql 模塊中的類大多具備lastError()函數,用於檢查最新出現的錯誤。若是你發現數據庫操做有任何問題,應該使用這個函數進行錯誤的檢查。
錯誤:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7
QSqlError("", "Driver not loaded", "Driver not loaded")
解決方式:
將MYSQL中bin文件夾下的名爲「libmysql.dll」,複製到QT中bin文件夾中。
添加後,測試下可否打開數據庫,並獲取數據,語句以下:
//提供執行和查詢的狀態,用於數據操做
QSqlQuery query;
//查詢數據庫
query.exec("SELECT * FROM student;");
//查詢數據庫中的第一條數據
query.first();
qDebug()<<query.value("id").toInt();
<<query.value("sname").toString();
<<query.value("age").toString();
<<query.value("score").toInt();
結果顯示:
QVariant(int, 8) QVariant(QString, "xiao") QVariant(int, 7) QVariant(int, 22)
數據庫表:
能夠看出已經成功接入數據庫,並能夠獲取數據。
QsqlQuery類
提供了一個執行和查詢的狀態,該類封裝了函數提取和檢索數據的功能,它能夠被用作數據操做語句,如:select,insert,update,selete,也能夠做爲數據定義語句,如:create table xxx;
QsqlQuery相似與鏈表的表頭指針,能夠獲取下一結點next()或上一結點previous()或其餘。。。
經常使用成員函數:
bool QSqlQuery::next()
bool QSqlQuery::previous()
bool QSqlQuery::first()
bool QSqlQuery::last()
bool QSqlQuery::seek(int index, bool relative = false)
For example:
QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
QString country = query.value(0).toString();
doSomething(country);
}
注意點:
如何操做多個數據庫?
函數原型:
QSqlDatabase QSqlDatabase::addDatabase(const QString & type, const QString & connectionName = QLatin1String( defaultConnection ))
第二參數是一個標識,能夠自擬。
好比:在數據庫中有兩個數據庫,database1,database2.
QSqlDatabase db1=QSqlDatabase::addDatabase( "QMYSQL");
QSqlDatabase db2=QSqlDatabase::addDatabase( "QMYSQL");
能夠這麼使用。可是本身又如何區別呢?可能在後面就忘記了db1,db2分別鏈接了哪一個數據庫。
改進:
QSqlDatabase db1=QSqlDatabase::addDatabase( "QMYSQL",「database1」);
QSqlDatabase db2=QSqlDatabase::addDatabase( "QMYSQL",「database2」);
第二個參數能夠指定一個別名,做爲標誌。
那麼,在執行操做時,必定要指定操縱哪一個數據庫。
QSqlQuery query(db1);
QSqlQuery query(db1);
不能夠默認。QSqlQuery query;
源代碼:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QtSql/QSqlDatabase>
#include <QSqlError>
#include <QtSql/QSqlQuery>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//查詢qt支持的數據庫驅動
qDebug()<<QSqlDatabase::drivers();
//添加數據庫
QSqlDatabase db=QSqlDatabase::addDatabase( "QMYSQL");
//鏈接數據庫
db.setHostName("localhost");
//db.setHostName("127.0.0.1");
db.setUserName("root");
//db.setPassword("123456");
db.setDatabaseName("stu");
//打開數據庫
if(!db.open())
{
qDebug()<<db.lastError();
}
//提供執行和查詢的狀態,用於數據操做
QSqlQuery query;
//查詢數據庫
query.exec("SELECT * FROM student;");
//查詢數據庫中的第一天數據
query.first();
qDebug()<<query.value("id").toInt()
<<query.value("sname").toString()
<<query.value("age").toString()
<<query.value("score").toInt();
}
Widget::~Widget()
{
delete ui;
}