當前位置:編程學習大全網 - 源碼下載 - 用qt怎麽備份Oracle數據庫

用qt怎麽備份Oracle數據庫

Qt 提供了 QtSql 模塊來提供平臺獨立的基於 SQL 的數據庫操作。這裏我們所說的“平臺獨立”,既包括操作系統平臺,有包括各個數據庫平臺。另外,我們強調了“基於 SQL”,因為 NoSQL 數據庫至今沒有壹個通用查詢方法,所以不可能提供壹種通用的 NoSQL 數據庫的操作。Qt 的數據庫操作還可以很方便的與 model/view 架構進行整合。通常來說,我們對數據庫的操作更多地在於對數據庫表的操作,而這正是 model/view 架構的長項。

Qt 使用QSqlDatabase表示壹個數據庫連接。更底層上,Qt 使用驅動(drivers)來與不同的數據庫 API 進行交互。Qt 桌面版本提供了如下幾種驅動:

驅動 數據庫

QDB2 IBM DB2 (7.1 或更新版本)

QIBASE Borland InterBase

QMYSQL MySQL

QOCI Oracle Call Interface Driver

QODBC Open Database Connectivity (ODBC) – Microsoft SQL Server 及其它兼容 ODBC 的數據庫

QPSQL PostgreSQL (7.3 或更新版本)

QSQLITE2 SQLite 2

QSQLITE SQLite 3

QSYMSQL 針對 Symbian 平臺的SQLite 3

QTDS Sybase Adaptive Server (自 Qt 4.7 起廢除)

不過,由於受到協議的限制,Qt 開源版本並沒有提供上面所有驅動的二進制版本,而僅僅以源代碼的形式提供。通常,Qt 只默認搭載 QSqlite 驅動(這個驅動實際還包括 Sqlite 數據庫,也就是說,如果需要使用 Sqlite 的話,只需要該驅動即可)。我們可以選擇把這些驅動作為 Qt 的壹部分進行編譯,也可以當作插件編譯。

如果習慣於使用 SQL 語句,我們可以選擇QSqlQuery類;如果只需要使用高層次的數據庫接口(不關心 SQL 語法),我們可以選擇QSqlTableModel和QSqlRelationalTableModel。我們只介紹QSqlQuery類的使用。

在使用時,我們可以通過

QSqlDatabase::drivers();

1

找到系統中所有可用的數據庫驅動的名字列表。我們只能使用出現在列表中的驅動。由於默認情況下,QtSql 是作為 Qt 的壹個模塊提供的。為了使用有關數據庫的類,我們必須早 .pro 文件中添加這麽壹句:

QT += sql

1

這表示,我們的程序需要使用 Qt 的 core、gui 以及 sql 三個模塊。註意,如果需要同時使用 Qt4 和 Qt5 編譯程序,通常我們的 .pro 文件是這樣的:

QT += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

1

2

這兩句也很明確:Qt 需要加載 core、gui 和 sql 三個模塊,如果主板本大於 4,則再添加 widgets 模塊。

下面來看壹個簡單的函數:

bool connect(const QString &dbName)

{

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

// db.setHostName("host");

// db.setDatabaseName("dbname");

// db.setUserName("username");

// db.setPassword("password");

db.setDatabaseName(dbName);

if (!db.open()) {

QMessageBox::critical(0, QObject::tr("Database Error"),

db.lastError().text());

return false;

}

return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

我們使用connect()函數創建壹個數據庫連接。我們使用QSqlDatabase::addDatabase()靜態函數完成這壹請求,也就是創建了壹個QSqlDatabase實例。註意,數據庫連接使用自己的名字進行區分,而不是數據庫的名字。例如,我們可以使用下面的語句:

QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE", QString("con%1").arg(dbName));

1

此時,我們是使用addDatabase()函數的第二個參數來給這個數據庫連接壹個名字。在這個例子中,用於區分這個數據庫連接的名字是QString(“conn%1”).arg(dbName),而不是 “QSQLITE”。這個參數是可選的,如果不指定,系統會給出壹個默認的名字QSqlDatabase::defaultConnection,此時,Qt 會創建壹個默認的連接。如果妳給出的名字與已存在的名字相同,新的連接會替換掉已有的連接。通過這種設計,我們可以為壹個數據庫建立多個連接。

我們這裏使用的是 sqlite 數據庫,只需要指定數據庫名字即可。如果是數據庫服務器,比如 MySQL,我們還需要指定主機名、端口號、用戶名和密碼,這些語句使用註釋進行了簡單的說明。

接下來我們調用了QSqlDatabase::open()函數,打開這個數據庫連接。通過檢查open()函數的返回值,我們可以判斷數據庫是不是正確打開。

QtSql 模塊中的類大多具有lastError()函數,用於檢查最新出現的錯誤。如果妳發現數據庫操作有任何問題,應該使用這個函數進行錯誤的檢查。這壹點我們也在上面的代碼中進行了體現。當然,這只是最簡單的實現,壹般來說,更好的設計是,不要在數據庫操作中混雜界面代碼(並且將這個connect()函數放在壹個專門的數據庫操作類中)。

接下來我們可以在main()函數中使用這個connect()函數:

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

if (connect("demo.db")) {

QSqlQuery query;

if (!query.exec("CREATE TABLE student ("

"id INTEGER PRIMARY KEY AUTOINCREMENT,"

"name VARCHAR,"

"age INT)")) {

QMessageBox::critical(0, QObject::tr("Database Error"),

query.lastError().text());

return 1;

}

} else {

return 1;

}

return a.exec();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

main()函數中,我們調用這個connect()函數打開數據庫。如果打開成功,我們通過壹個QSqlQuery實例執行了 SQL 語句,就是query.exec();。同樣,我們使用其lastError()函數檢查了執行結果是否正確。

註意這裏的QSqlQuery實例的創建。我們並沒有指定是為哪壹個數據庫連接創建查詢對象,此時,系統會使用默認的連接,也就是使用沒有第二個參數的addDatabase()函數創建的那個連接(其實就是名字為QSqlDatabase::defaultConnection的默認連接)。如果沒有這麽壹個連接,系統就會報錯。也就是說,如果沒有默認連接,我們在創建QSqlQuery對象時必須指明是哪壹個QSqlDatabase對象,也就是addDatabase()的返回值。

我們還可以通過使用QSqlQuery::isActive()函數檢查語句執行正確與否。如果QSqlQuery對象是活動的,該函數返回 true。所謂“活動”,就是指該對象成功執行了exec()函數,但是還沒有完成。如果需要設置為不活動的,可以使用finish()或者clear()函數,或者直接釋放掉這個QSqlQuery對象。這裏需要註意的是,如果存在壹個活動的 SELECT 語句,某些數據庫系統不能成功完成connect()或者rollback()函數的調用。此時,我們必須首先將活動的 SELECT 語句設置成不活動的。

創建過數據庫表 student 之後,我們開始插入數據,然後將其獨取出來:

if (connect("demo.db")) {

QSqlQuery query;

query.prepare("INSERT INTO student (name, age) VALUES (?, ?)");

QVariantList names;

names << "Tom" << "Jack" << "Jane" << "Jerry";

query.addBindValue(names);

QVariantList ages;

ages << 20 << 23 << 22 << 25;

query.addBindValue(ages);

if (!query.execBatch()) {

QMessageBox::critical(0, QObject::tr("Database Error"),

query.lastError().text());

}

query.finish();

query.exec("SELECT name, age FROM student");

while (query.next()) {

QString name = query.value(0).toString();

int age = query.value(1).toInt();

qDebug() << name << ": " << age;

}

} else {

return 1;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

依舊連接到我們創建的 demo.db 數據庫。我們需要插入多條數據,此時可以使用QSqlQuery::exec()函數壹條壹條插入數據,但是這裏我們選擇了另外壹種方法:批量執行。首先,我們使用QSqlQuery::prepare()函數對這條 SQL 語句進行預處理,問號 ? 相當於占位符,預示著以後我們可以使用實際數據替換這些位置。簡單說明壹下,預處理是數據庫提供的壹種特性,它會將 SQL 語句進行編譯,性能和安全性都要優於普通的 SQL 處理。在上面的代碼中,我們使用壹個字符串列表 names 替換掉第壹個問號的位置,壹個整型列表 ages 替換掉第二個問號的位置,利用QSqlQuery::addBindValue()我們將實際數據綁定到這個預處理的 SQL 語句上。需要註意的是,names 和 ages 這兩個列表裏面的數據需要壹壹對應。然後我們調用QSqlQuery::execBatch()批量執行 SQL,之後結束該對象。這樣,插入操作便完成了。

另外說明壹點,我們這裏使用了 ODBC 風格的 ? 占位符,同樣,我們也可以使用 Oracle 風格的占位符:

query.prepare("INSERT INTO student (name, age) VALUES (:name, :age)");

1

此時,我們就需要使用

query.bindValue(":name", names);

query.bindValue(":age", ages);

1

2

進行綁定。Oracle 風格的綁定最大的好處是,綁定的名字和值很清晰,與順序無關。但是這裏需要註意,bindValue()函數只能綁定壹個位置。比如

query.prepare("INSERT INTO test (name1, name2) VALUES (:name, :name)");

// ...

query.bindValue(":name", name);

1

2

3

只能綁定第壹個 :name 占位符,不能綁定到第二個。

接下來我們依舊使用同壹個查詢對象執行壹個 SELECT 語句。如果存在查詢結果,QSqlQuery::next()會返回 true,直到到達結果最末,返回 false,說明遍歷結束。我們利用這壹點,使用 while 循環即可遍歷查詢結果。使用QSqlQuery::value()函數即可按照 SELECT 語句的字段順序獲取到對應的數據庫存儲的數據。

對於數據庫事務的操作,我們可以使用 QSqlDatabase::transaction() 開啟事務,QSqlDatabase::commit() 或者QSqlDatabase::rollback() 結束事務。使用QSqlDatabase::database()函數則可以根據名字獲取所需要的數據庫連接。

  • 上一篇:急!關於VB,簡單的程序設計
  • 下一篇:控制銀行IT系統運維風險的手段有哪些?
  • copyright 2024編程學習大全網