QT - sqlite數據庫的使用

前言

SQLite(sql)是一款開源輕量級的數據庫軟件,不需要server,可以集成在其他軟件中,非常適合嵌入式系統。
Qt5以上版本可以直接使用SQLite(Qt自帶驅動)。

用法

1 準備

  1. 引入SQL模塊
    在Qt項目文件(.pro文件)中,加入SQL模塊:
QT += sql
  1. 引用頭文件
    在需要使用SQL的類定義中,引用相關頭文件。例如:
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>

2 使用

1. 建立數據庫

檢查連接、添加數據庫驅動、設置數據庫名稱、數據庫登錄用戶名、密碼。

QSqlDatabase database;
if (QSqlDatabase::contains("qt_sql_default_connection"))
{
    database = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
    database = QSqlDatabase::addDatabase("QSQLITE");
    database.setDatabaseName("MyDataBase.db");
    database.setUserName("XingYeZhiXia");
    database.setPassword("123456");
}

上述代碼解釋:
(1)第一行中,建立了一個QSqlDatabase對象,後續的操作要使用這個對象。
(2)if語句用來檢查指定的連接(connection)是否存在。這裏指定的連接名稱(connection name)是qt_sql_default_connection,這是Qt默認連接名稱。實際使用時,這個名稱可以任意取。如果判斷此連接已經存在,那麼QSqlDatabase::contains()函數返回true。此時,進入第一個分支,QSqlDatabase::database()返回這個連接。
(3)如果這個連接不存在,則進入else分支,需要創建連接,並添加數據庫。在else分支第一行,addDatabase()的參數QSQLITE是SQLite對應的驅動名,不能改。而且需要注意的是,addDatabase()的第二個參數被省略了,第二個參數的默認參數就是上面提到的Qt默認連接名稱qt_sql_default_connection。如果需要使用自定義的連接名稱(如果程序需要處理多個數據庫文件的話就會這樣),則應該加入第二個參數,例如

database = QSqlDatabase::addDatabase("QSQLITE", "my_sql_connection);

這個時候,如果在另一個地方需要判斷my_sql_connection連接是否存在,就應該使用if (QSqlDatabase::contains("my_sql_connection"))
(4)else分支第二行中,setDatabaseName()的參數是數據庫文件名。如果這個數據庫不存在,則會在後續操作時自動創建;如果已經存在,則後續的操作會在已有的數據庫上進行。
(5)else分支後面兩行,設置用戶名和密碼。用戶名,密碼都可以隨便取,也可以省略。

2. 打開數據庫

使用open()打開數據庫,並判斷是否成功。注意,在第一步檢查連接是否存在時,如果連接存在,則在返回這個連接的時候,會默認將數據庫打開。

if (!database.open())
{
    qDebug() << "Error: Failed to connect database." << database.lastError();
}
else
{
    // do something
}

如果打開成功,則進入else分支。對數據庫的操作都需要在else分支中進行。

3. 關閉數據庫

數據庫操作完成後,最好關閉。

    database.close();

4. 操作數據庫

對數據庫進行操作需要用到QSqlQuery類,操作前必須定義一個對象。下面舉例說明操作方法。操作需要使用SQLite語句,本文中的幾個例子會使用幾個常用的語句,關於SQLite語句的具體信息請參考SQLite相關資料。
例1:創建表格
創建一個名爲student的表格,表格包含三列,第一列是id,第二列是名字,第三列是年齡。

QSqlQuery sql_query;
QString create_sql = "create table student (id int primary key, name varchar(30), age int)";
sql_query.prepare(create_sql);
if(!sql_query.exec())
{
    qDebug() << "Error: Fail to create table." << sql_query.lastError();
}
else
{
    qDebug() << "Table created!";
}

代碼解釋:
(1)第一行定義一個QSqlQuery對象。
(2)第二行是一個QString,其中的內容是SQLite語句。對數據庫的操作,都是用SQLite的語句完成的,把這些指令以QString類型,通過prepare函數,保存在QSqlQuery對象中。也可將指令,以QString形式直接寫在exec()函數的參數中,例如:

    sql_query.exec("create table student (id int primary key, name varchar(30), age int)");

創建表格語句:create table <table_name> (f1 type1, f2 type2,…);
create table是創建表格的語句,也可用大寫CREATE TABLE;student是表格的名稱,可以任意取;括號中是表格的格式,上述指令表明,表格中有三列,第一列的名稱(表頭)是id,這一列儲存的數據類型是int,第二列名稱是name,數據類型是字符數組,最多有30個字符(和char(30)的區別在於,varchar的實際長度是變化的,而char的長度始終是給定的值),第三列的名稱是age,數據類型是int。
如果sql_query.exec()執行成功,則創建表格成功。

例2:插入數據
在剛纔創建的表格中,插入一行數據。

QString insert_sql = "insert into student values (?, ?, ?)";
sql_query.prepare(insert_sql);
sql_query.addBindValue(max_id+1);
sql_query.addBindValue("Wang");
sql_query.addBindValue(25);
if(!sql_query.exec())
{
    qDebug() << sql_query.lastError();
}
else
{
    qDebug() << "inserted Wang!";
}
if(!sql_query.exec("INSERT INTO student VALUES(3, \"Li\", 23)"))
{
    qDebug() << sql_query.lastError();
}
else
{
    qDebug() << "inserted Li!";
}

插入語句:insert into <table_name> values (value1, value2,…);
insert into是插入語句,student是表格名稱,values()是要插入的數據。這裏,我們插入了2組數據。插入第一組數據的時候,用addBindValue來替代語句中的?,替代的順序與addBindValue調用的順序相同。插入第二組數據的時候,則是直接寫出完整語句。

例3:更新數據(修改數據)

QString update_sql = "update student set name = :name where id = :id";
sql_query.prepare(update_sql);
sql_query.bindValue(":name", "Qt");
sql_query.bindValue(":id", 1);
if(!sql_query.exec())
{
    qDebug() << sql_query.lastError();
}
else
{
    qDebug() << "updated!";
}

語句:update <table_name> set <f1=value1>, <f2=value2>… where <expression>;
更新(修改)的語句是update...set...,其中student是表格名稱,name是表頭名稱(即第二列),:name是待定的變量,where用於確定是哪一組數據,:id也是待定變量。
bindValue(" ", " ")函數用來把語句中的待定變量換成確定值。

例4:查詢數據
(1)查詢部分數據

QString select_sql = "select id, name from student";
if(!sql_query.exec(select_sql))
{
    qDebug()<<sql_query.lastError();
}
else
{
    while(sql_query.next())
    {
        int id = sql_query.value(0).toInt();
        QString name = sql_query.value(1).toString();
        qDebug()<<QString("id:%1    name:%2").arg(id).arg(name);
    }
}

語句select <f1>, <f2>, ... from <table_name>;
select是查詢指令;<f1> 等等是要查詢的變量(即表頭),中間用逗號隔開;from ...指定表格。
上述語句是說查詢student表中的 id 和 name 。執行查詢之後,用sql_query.value(int)來獲得數據。同樣地,value(0)表示第一個數據,即 id,value(1)表示name。注意value()函數的返回值類型是QVariant,因此要用toInt()等函數轉換成特定的類型。
(2)查詢全部數據

QString select_all_sql = "select * from student";
sql_query.prepare(select_all_sql);
if(!sql_query.exec())
{
    qDebug()<<sql_query.lastError();
}
else
{
    while(sql_query.next())
    {
        int id = sql_query.value(0).toInt();
        QString name = sql_query.value(1).toString();
        int age = sql_query.value(2).toInt();
        qDebug()<<QString("id:%1    name:%2    age:%3").arg(id).arg(name).arg(age);
    }
}

語句select * from <table_name>;
查詢所有數據用 * 表示。用while(sql_query.next())用來遍歷所有行。同樣用value()獲得數據。
(3)查詢最大id

QString select_max_sql = "select max(id) from student";
int max_id = 0;
sql_query.prepare(select_max_sql);
if(!sql_query.exec())
{
    qDebug() << sql_query.lastError();
}
else
{
    while(sql_query.next())
    {
        max_id = sql_query.value(0).toInt();
        qDebug() << QString("max id:%1").arg(max_id);
    }
}

這個就是在語句中用max來獲取最大值。

例5:刪除與清空
(1)刪除一條數據

QString delete_sql = "delete from student where id = ?";
sql_query.prepare(delete_sql);
sql_query.addBindValue(0);
if(!sql_query.exec())
{
    qDebug()<<sql_query.lastError();
}
else
{
    qDebug()<<"deleted!";
}

語句delete from <table_name> where <f1> = <value>
delete用於刪除條目,用where給出限定條件。例如此處是刪除 id = 0的條目。
(2)清空表格(刪除所有)

QString clear_sql = "delete from student";
sql_query.prepare(clear_sql);
if(!sql_query.exec())
{
    qDebug() << sql_query.lastError();
}
else
{
    qDebug() << "table cleared";
}

這裏沒有用where給出限制,就會刪除所有內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章