首先,要查詢相關的驅動是否已經裝好了,可以用以下的程序進行驗證:
#include <QtCore/QCoreApplication>
#include <QSqlDatabase>
#include <QDebug>
#include <QStringList>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"Available drivers:";
QStringList drivers = QSqlDatabase::drivers();
foreach(QString driver, drivers)
qDebug() <<"/t" << driver;
return a.exec();
}
結果如下:
接着是連接數據庫:
#include <QtGui/QApplication>
#include <QtGui>
#include <QtSql>
bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("test");
db.setUserName("root");
db.setPassword("123456");
bool ok = db.open();
if(!ok){
QMessageBox::critical(0, QObject::tr(" 連接數據庫失敗!!! "), db.lastError().text());
return false;
}else{
QMessageBox::information(0, QObject::tr("Tips"), QObject::tr(" 連接數據庫成功!!! "));
return true;
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec *codec= QTextCodec::codecForName("GB2312");
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
if(!createConnection())
return 1;
return a.exec();
}
結果如下:
插入操作:
//ODBC 數據庫表示方式
QSqlQuery query;
query.prepare( “insert into student (id, name)
”
“values (:id, :name) ”);
query.bindValue(0, 5);
query.bindValue(1, “sixth ”);
query.exec();
//Oracle 表示方式
query.prepare(
“insert into student (id, name)
”
“values (?, ?) ”);
query.bindValue(0, 5);
query.bindValue(1, “sixth ”);
query.exec();
// 使用 addBindValue() 函數,省去了編號,它是按屬性順序賦值的
query.prepare(
“insert into student (id, name)
”
“values (?, ?) ”);
query.addBindValue(5);
query.addBindValue( “sixth ”);
query.exec();
// 使用 ODBC 方法時,可以將編號用實際的佔位符代替
query.prepare(
“insert into student (id, name)
”
“values (:id, :name) ”);
query.bindValue( “:id ”, 5);
query.bindValue( “:name ”,
“sixth ”);
query.exec();
注意:最後一定要執行 exec() ,否則上面的語句是不會被執行的。
// 進行多個記錄的插入時,可以利用綁定進行批處理
QSqlQuery q;
q.prepare( “insert into student values (?, ?) ”);
QVariantList ints;
ints << 10 << 11 << 12 << 13;
q.addBindValue(ints);
QVariantList names;
names << “xiaoming ” <<
“xiaoliang ” << “xiaogang ” << QVariant(QVariant::String);
// 最後一個是空字符串,應與前面的格式相同
q.addBindValue(names);
if (!q.execBatch()) //
進行批處理,如果出錯就輸出錯誤
qDebug() << q.lastError();
查詢操作:
// 返回全部的屬性和結果集
QSqlQuery query;
query.exec( “select * from student ”);// 執行查詢操作
qDebug() << “exec next() : ”;
if(query.next())
// 開始就先執行一次next() 函數,那麼query 指向結果集的第一條記錄
{
int rowNum = query.at();
// 獲取query 所指向的記錄在結果集中的編號
int columnNum = query.record().count();
// 獲取每條記錄中屬性(即列)的個數
int fieldNo = query.record().indexOf(
“name ”);
// 獲取
” name
”屬性所在列的編號,列從左向右編號,最左邊的編號爲
0
int id = query.value(0).toInt();
// 獲取id 屬性的值,並轉換爲int 型
QString name = query.value(fieldNo).toString();
// 獲取name 屬性的值
qDebug() << “rowNum is :
” << rowNum // 將結果輸出
<< ” id is :
” << id
<< ” name is : ” <<name
<< ” columnNum is : ” << columnNum;
}
qDebug() << “exec seek(2) : ”;
if(query.seek(2))
// 定位到結果集中編號爲2 的記錄,即第三條記錄,因爲第一條記錄的編號爲
0
{
qDebug() << “rowNum is :
” <<query.at()
<< ” id is : ” <<query.value(0).toInt()
<< ” name is : ” <<query.value(1).toString();
}
qDebug() << “exec last() : ”;
if(query.last())
// 定位到結果集中最後一條記錄
{
qDebug() << “rowNum is :
” <<query.at()
<< ” id is : ” << query.value(0).toInt()
<< ” name is : ” <<query.value(1).toString();
}
結果集其實就是查詢到的所有記錄的集合,而在QSqlQuery 類中提供了多個函數來操作這個集合,需要注意這個集合中的記錄是從 0 開始編號的。最常用的有:
seek(int n) :query 指向結果集的第n 條記錄。
first() :query 指向結果集的第一條記錄。
last() :query 指向結果集的最後一條記錄。
next() :query 指向下一條記錄,每執行一次該函數,便指向相鄰的下一條記錄。
previous() :query 指向上一條記錄,每執行一次該函數,便指向相鄰的上一條記錄。
record() :獲得現在指向的記錄。
value(int n) :獲得屬性的值。其中n 表示你查詢的第n 個屬性,比方上面我們使用 “ select * from student ”就相當於 “ select id, name from student ”,那麼value(0) 返回id 屬性的值,value(1) 返回name 屬性的值。該函數返回QVariant 類型的數據,關於該類型與其他類型的對應關係,可以在幫助中查看QVariant 。
at() :獲得現在query 指向的記錄在結果集中的編號。
需要說明,當剛執行完query.exec( “select * from student ”); 這行代碼時,query 是指向結果集以外的,我們可以利用query.next() ,當第一次執行這句代碼時,query 便指向了結果集的第一條記錄。當然我們也可以利用seek(0) 函數或者first() 函數使query 指向結果集的第一條記錄。但是爲了節省內存開銷,推薦的方法是,在query.exec( “select * from student ”); 這行代碼前加上query.setForwardOnly(true); 這條代碼,此後只能使用next() 和seek() 函數。
// 滿足一定條件的結果集,方法一
QSqlQuery query;
query.prepare( “select name from student where id = ? ”);
int id =2; // 從界面獲取id 的值
query.addBindValue(id); //
將id 值進行綁定
query.exec();
query.next(); // 指向第一條記錄
qDebug() << query.value(0).toString();
// 方法二
QSqlQuery query;
query. exec( QObject :: tr( "select * from student where id = %1" ). arg( 2 ));
if (! query. next())
qDebug()<< "none" ;
else
qDebug()<< query. value( 0 ). toInt()<< query. value( 1 ). toString();
事務是數據庫的一個重要功能,所謂事務是用戶定義的一個數據庫操作序列,這些操作要麼全做要麼全不做,是一個不可分割的工作單位。在Qt 中用transaction() 開始一個事務操作,用commit() 函數或rollback() 函數進行結束。commit() 表示提交,即提交事務的所有操作。具體地說就是將事務中所有對數據庫的更新寫回到數據庫,事務正常結束。rollback() 表示回滾,即在事務運行的過程中發生了某種故障,事務不能繼續進行,系統將事務中對數據庫的所有已完成的操作全部撤銷,回滾到事務開始時的狀態。
QSqlQuery query;
if(QSqlDatabase::database().transaction()) //
啓動事務操作
{
// 下面執行各種數據庫操作
query.exec( “insert into student values (14, ‘hello’) ”);
query.exec( “delete from student where id = 1 ″);
//
if(!QSqlDatabase::database().commit())
{
qDebug() << QSqlDatabase::database().lastError(); //
提交
if(!QSqlDatabase::database().rollback())
qDebug() << QSqlDatabase::database().lastError(); //
回滾
}
}
// 輸出整張表
query.exec(
“select * from student ”);
while(query.next())
qDebug() << query.value(0).toInt() << query.value(1).toString();
Qt 中使用了自己的機制來避免使用SQL 語句,它爲我們提供了更簡單的數據庫操作和數據顯示模型。它們分別是隻讀的QSqlQueryModel ,操作單表的QSqlTableModel 和以及可以支持外鍵的QSqlRelationalTableModel
// QSqlQueryModel
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery( “select * from student ”);
model->setHeaderData(0, Qt::Horizontal, tr( “id ”));
model->setHeaderData(1, Qt::Horizontal, tr( “name ”));
QTableView *view = new QTableView;
view->setModel(model);
view->show();
//QSqlTableModel
QSqlTableModel *model;
model = new QSqlTableModel(this);
model->setTable( “student ”);
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select(); // 選取整個表的所有行
// model->removeColumn(1); //
不顯示name 屬性列
,
如果這時添加記錄,則該屬性的值添加不上
ui->tableView->setModel(model);
// ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); //
使其不可編輯
// 過濾
model->setFilter(QObject::tr(“name = ‘%1
′”).arg(name)); // 根據姓名進行篩選
model->select(); //
顯示結果
// 刪除操作
int curRow = ui->tableView->currentIndex().row();
// 獲取選中的行
model->removeRow(curRow);
// 刪除該行
int ok = QMessageBox::warning(this,tr(
“刪除當前行! ”),tr( “你確定
”
“刪除當前行嗎?
”
),
QMessageBox::Yes,QMessageBox::No);
if(ok == QMessageBox::No)
{
model->revertAll(); // 如果不刪除,則撤銷
}
else
model->submitAll(); //
否則提交,在數據庫中刪除該行
// 插入操作
int rowNum = model->rowCount(); //
獲得表的行數
int id = 10;
model->insertRow(rowNum); //
添加一行
model->setData(model->index(rowNum,0),id);
model->submitAll();//
記得提交
//QSqlRelationalTableModel
// create table student (id int primary key, name vchar,course int)
// create table course (id int primary key, name vchar, teacher vchar)
model = new QSqlRelationalTableModel(this);
model->setEditStrategy(QSqlTableModel::OnFieldChange); //
屬性變化時寫入數據庫
model->setTable(
“student ”);
model->setRelation(2,QSqlRelation( “course ”, ”id ”, ”name ”));
// 將student 表的第三個屬性設爲course 表的id 屬性的外鍵,並將其顯示爲course 表的name 屬性的值
model->setHeaderData(0, Qt::Horizontal, QObject::tr(
“ID ”));
model->setHeaderData(1, Qt::Horizontal, QObject::tr( “Name ”));
model->setHeaderData(2, Qt::Horizontal, QObject::tr( “Course ”));
model->select();
ui->tableView->setModel(model);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));// 如果用戶更改課程屬性,那麼他只能在課程表中有的課程中進行選擇,而不能隨意填寫課程。在Qt 中的QSqlRelationalDelegate 委託類就能實現這個功能。我們只需添加一行代碼
該文是根據http://hi.baidu.com/yafeilinux/上的資料整理的