Qt が SQLite データベースを操作する方法

1. SQLite の紹介

Qtのプロジェクト開発でよく使われる軽量データベースとして、Sqliteデータベースは比較的相性の良いデータベースの1つと言えます(MicrosoftがAccessデータベースと互換性があるように、SqliteはQtの息子のようなものです)。Qt5 より上のバージョンは直接使用でき (Qt には独自のドライバーが付属しています)、軽量なデータベースです. 一般的に言えば、次のような利点があります。

  • SQLite の設計目的は、純粋な C 言語コードに基づく組み込み SQL データベース エンジンであり、非常に幅広い分野で使用されています。
  • SQLite は、データ ファイル (.db) を長期間保存する必要がある場合は、ハードディスク上のデータ ファイル (.db) を直接読み取ることができます。また、長期間保存する必要がない場合は、データベース全体をメモリに格納することもできます。そのうち、追加のサーバー側プロセス、つまり SQLite が必要です。これは、独立して実行する必要のないデータベース エンジンです。
  • ソース コードはオープン ソースであり、販売を含め、何にでも使用できます。
  • ゼロ構成 – 構成をインストールして管理する必要はありません。
  • 構成もインストールも管理者も不要です。
  • 同じデータ ファイルを異なるマシンで使用でき、エンディアンが異なるマシン間で自由に共有できます。
  • 複数の開発言語、C、C++、PHP、Perl、Java、C#、Python、Ruby などをサポートします。

この記事の特典として、 Qt 開発学習教材パッケージ、テクニカル ビデオ (C++ 言語の基礎、C++ デザイン パターン、Q​​t プログラミング入門、QT シグナルとスロット メカニズム、QT インターフェイス開発イメージ図、QT ネットワーク、QT を含む) を無料で受け取ることができます。データベースプログラミング、QTプロジェクト実戦、QSS、OpenCV、Quickモジュール、取材質問等) ↓↓↓↓↓↓下記参照↓↓料金の受け取りは記事下部をクリック↓↓

2.使い方

2.1. 準備

1. SQL モジュールの導入

Qt プロジェクト ファイル (.pro ファイル) で、SQL モジュールを追加します。

QT += sql

2.ヘッダーファイルを参照する

SQL を使用する必要があるクラス定義では、関連するヘッダー ファイルを参照してください。例えば:

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>

2.2. 使用

1.データベースを作成する

QSqlDatabase database;
 
if (QSqlDatabase::contains("qt_sql_default_connection"))
{
    database = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
    // 建立和SQlite数据库的连接
    database = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库文件的名字
    database.setDatabaseName("MyDataBase.db");
}

最初の行では、QSqlDatabase オブジェクトが確立され、後続の操作はこのオブジェクトを使用します。

指定した接続(接続)が存在するかどうかをif文で確認します。ここで指定する接続名は qt_sql_default_connection で、これは Qt のデフォルトの接続名です。実際の使用では、この名前は任意に選択できます。接続が既に存在すると判断された場合、QSqlDatabase::contains() 関数は true を返します。この時点で、最初のブランチに入ると、QSqlDatabase::database() が接続を返します。

この接続が存在しない場合は、else ブランチに入り、接続を作成してデータベースを追加する必要があります。else ブランチの 1 行目で、addDatabase() のパラメーター QSQLITE は SQLite に対応するドライバー名であり、変更できません。そして、addDatabase() の 2 番目のパラメーターが省略されていることに注意してください。2 番目のパラメーターの既定のパラメーターは、前述の Qt の既定の接続名 qt_sql_default_connection です。カスタム接続名を使用する必要がある場合 (プログラムが複数のデータベース ファイルを処理する必要がある場合)、次のように 2 番目のパラメーターを追加する必要があります。

データベース = QSqlDatabase::addDatabase("QSQLITE", "my_sql_connection);

この時点で、mysql_connection 接続が別の場所に存在するかどうかを判断する必要がある場合は、if (QSqlDatabase::contains("my_sql_connection")) を使用する必要があります。

else ブランチの 2 行目にある setDatabaseName() のパラメーターは、データベース ファイル名です。データベースが存在しない場合は、後続の操作で自動的に作成されます。データベースが既に存在する場合は、既存のデータベースに対して後続の操作が実行されます。

2.データベースを開く

open() を使用してデータベースを開き、成功したかどうかを判断します。最初のステップで接続が存在するかどうかを確認するときに、接続が存在する場合は、接続が返されたときにデフォルトでデータベースが開かれることに注意してください。

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

データベースが正常に開かれた場合は、else ブランチに入ります。データベースに対するすべての操作は、else ブランチで実行する必要があります。

3. データベースを閉じる

データベースの操作が完了したら、データベースを閉じることをお勧めします。

database.close();

4. データベースの操作

データベースを操作するには QSqlQuery クラスが必要であり、操作の前にオブジェクトを定義する必要があります。次の例は、操作方法を示しています。

例 1: テーブルを作成する

3 つの列 (最初の列は id、2 番目の列は名前、3 番目の列は年齢) を持つ、student という名前のテーブルを作成します。

// 用于执行sql语句的对象
QSqlQuery sqlQuery;
// 构建创建数据库的sql语句字符串
QString createSql = QString("CREATE TABLE student (\
                          id INT PRIMARY KEY NOT NULL,\
                          name TEXT NOT NULL,\
                          age INT NOT NULL)");
sqlQuery.prepare(createSql);
// 执行sql语句
if(!sqlQuery.exec())
{
    qDebug() << "Error: Fail to create table. " << sqlQuery.lastError();
}
else
{     qDebug() << "Table created!";
}

最初の行は QSqlQuery オブジェクトを定義します。

2 行目は QString で、その内容は SQLite ステートメントです。データベースでの操作はすべて SQLite ステートメントで完了し、これらの命令は prepare 関数を通じて QString タイプとして QSqlQuery オブジェクトに格納されます。命令は、QString の形式で exec() 関数のパラメーターに直接書き込むこともできます。次に例を示します。

sql_query.exec("CREATE TABLE 生徒 (ID INT PRIMARY KEY NOT NULL, ...)");

sql_query.exec() が正常に実行されると、テーブルが正常に作成されます。

例 2: 1 行のデータを挿入する

作成したばかりのテーブルに、1 行のデータを挿入します。

// 方法一:使用 bindValue 函数插入单行数据
QSqlQuery sqlQuery;
sqlQuery.prepare("INSERT INTO student VALUES(:id,:name,:age)");
sqlQuery.bindValue(":id", max_id + 1);
sqlQuery.bindValue(":name", "Wang");
sqlQuery.bindValue(":age", 25);
if(!sqlQuery.exec())
{
    qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
}
else
{
    // do something    
}
 
// 方法二:使用 addBindValue 函数插入单行数据
QSqlQuery sqlQuery;
sqlQuery.prepare("INSERT INTO student VALUES(?, ?, ?)");
sqlQuery.addBindValue(max_id + 1);
sqlQuery.addBindValue("Wang");
sqlQuery.addBindValue(25);
if(!sqlQuery.exec())
{
    qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
}
else
{
    // do something    
}
 
// 方法三:直接写出完整语句
if(!sql_query.exec("INSERT INTO student VALUES(3, \"Li\", 23)"))
{
    qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
}
else
{
    // do something 
}

例 3: すべてのデータを照会する

QSqlQuery sqlQuery;
sqlQuery.exec("SELECT * FROM student");
if(!sqlQuery.exec())
{
    qDebug() << "Error: Fail to query table. " << sqlQuery.lastError();
}
else
{
    while(sqlQuery.next())
    {
        int id = sqlQuery.value(0).toInt();
        QString name = sqlQuery.value(1).toString();
        int age = sqlQuery.value(2).toInt();
        qDebug()<<QString("id:%1    name:%2    age:%3").arg(id).arg(name).arg(age);
    }
}

例 4: データを更新する (データを変更する)

QSqlQuery sqlQuery;
sqlQuery.prepare("UPDATE student SET name=?,age=? WHERE id=?");
sqlQuery.addBindValue(name);
sqlQuery.addBindValue(age);
sqlQuery.addBindValue(id);
if(!sqlQuery.exec())
{
    qDebug() << sqlQuery.lastError();
}
else
{
    qDebug() << "updated data success!";
}

3. サンプルプログラムの完成

上記は一般的に使用される SQL ステートメントのほんの一部の例であり、完全なサンプル プログラムは以下に掲載されています。

SqliteOperator.h

#ifndef SQLITEOPERATOR_H
#define SQLITEOPERATOR_H
 
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
 
typedef struct
{
    int id;
    QString name;
    int age;
}w2dba;
 
class SqliteOperator
{
public:
    SqliteOperator();
 
    // 打开数据库
    bool openDb(void);
    // 创建数据表
    void createTable(void);
    // 判断数据表是否存在
    bool isTableExist(QString& tableName);
    // 查询全部数据
    void queryTable();
    // 插入数据
    void singleInsertData(w2dba &singleData); // 插入单条数据
    void moreInsertData(QList<w2dba> &moreData); // 插入多条数据
    // 修改数据
    void modifyData(int id, QString name, int age);
    // 删除数据
    void deleteData(int id);
    //删除数据表
    void deleteTable(QString& tableName);
    // 关闭数据库
    void closeDb(void);
 
private:
    QSqlDatabase database;// 用于建立和数据库的连接
};
 
#endif //  SQLITEOPERATOR_H

SqliteOperator.cpp

#include "sqliteoperator.h"
 
// 构造函数中初始化数据库对象,并建立数据库
SqliteOperator::SqliteOperator()
{
    if (QSqlDatabase::contains("qt_sql_default_connection"))
    {
        database = QSqlDatabase::database("qt_sql_default_connection");
    }
    else
    {
        // 建立和SQlite数据库的连接
        database = QSqlDatabase::addDatabase("QSQLITE");
        // 设置数据库文件的名字
        database.setDatabaseName("MyDataBase.db");
    }
}
 
// 打开数据库
bool SqliteOperator::openDb()
{
    if (!database.open())
    {
        qDebug() << "Error: Failed to connect database." << database.lastError();
    }
    else
    {
        // do something
    }
 
    return true;
}
 
// 创建数据表
void SqliteOperator::createTable()
{
    // 用于执行sql语句的对象
    QSqlQuery sqlQuery;
    // 构建创建数据库的sql语句字符串
    QString createSql = QString("CREATE TABLE student (\
                          id INT PRIMARY KEY NOT NULL,\
                          name TEXT NOT NULL,\
                          age INT NOT NULL)");
    sqlQuery.prepare(createSql);
    // 执行sql语句
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to create table. " << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "Table created!";
    }
}
 
// 判断数据库中某个数据表是否存在
bool SqliteOperator::isTableExist(QString& tableName)
{
    QSqlDatabase database = QSqlDatabase::database();
    if(database.tables().contains(tableName))
    {
        return true;
    }
 
    return false;
}
 
// 查询全部数据
void SqliteOperator::queryTable()
{
    QSqlQuery sqlQuery;
    sqlQuery.exec("SELECT * FROM student");
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to query table. " << sqlQuery.lastError();
    }
    else
    {
        while(sqlQuery.next())
        {
            int id = sqlQuery.value(0).toInt();
            QString name = sqlQuery.value(1).toString();
            int age = sqlQuery.value(2).toInt();
            qDebug()<<QString("id:%1    name:%2    age:%3").arg(id).arg(name).arg(age);
        }
    }
}
 
// 插入单条数据
void SqliteOperator::singleInsertData(w2dba &singledb)
{
    QSqlQuery sqlQuery;
    sqlQuery.prepare("INSERT INTO student VALUES(:id,:name,:age)");
    sqlQuery.bindValue(":id", singledb.id);
    sqlQuery.bindValue(":name", singledb.name);
    sqlQuery.bindValue(":age", singledb.age);
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
    }
    else
    {
        // do something
    }
}
 
// 插入多条数据
void SqliteOperator::moreInsertData(QList<w2dba>& moredb)
{
    // 进行多个数据的插入时,可以利用绑定进行批处理
    QSqlQuery sqlQuery;
    sqlQuery.prepare("INSERT INTO student VALUES(?,?,?)");
    QVariantList idList,nameList,ageList;
    for(int i=0; i< moredb.size(); i++)
    {
        idList <<  moredb.at(i).id;
        nameList << moredb.at(i).name;
        ageList << moredb.at(i).age;
    }
    sqlQuery.addBindValue(idList);
    sqlQuery.addBindValue(nameList);
    sqlQuery.addBindValue(ageList);
 
    if (!sqlQuery.execBatch()) // 进行批处理,如果出错就输出错误
    {
        qDebug() << sqlQuery.lastError();
    }
}
 
// 修改数据
void SqliteOperator::modifyData(int id, QString name, int age)
{
    QSqlQuery sqlQuery;
    sqlQuery.prepare("UPDATE student SET name=?,age=? WHERE id=?");
    sqlQuery.addBindValue(name);
    sqlQuery.addBindValue(age);
    sqlQuery.addBindValue(id);
    if(!sqlQuery.exec())
    {
        qDebug() << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "updated data success!";
    }
}
 
// 删除数据
void SqliteOperator::deleteData(int id)
{
    QSqlQuery sqlQuery;
 
    sqlQuery.exec(QString("DELETE FROM student WHERE id = %1").arg(id));
    if(!sqlQuery.exec())
    {
        qDebug()<<sqlQuery.lastError();
    }
    else
    {
        qDebug()<<"deleted data success!";
    }
}
 
//删除数据表
void SqliteOperator::deleteTable(QString& tableName)
{
    QSqlQuery sqlQuery;
 
    sqlQuery.exec(QString("DROP TABLE %1").arg(tableName));
    if(sqlQuery.exec())
    {
        qDebug() << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "deleted table success";
    }
}
 
void SqliteOperator::closeDb(void)
{
    database.close();
}

main.cpp

#include <QCoreApplication>
#include "sqliteoperator.h"
#include <QString>
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    //创建并打开SQLite数据库
    SqliteOperator sqlTest;
    sqlTest.openDb();
 
    // 创建数据表
    sqlTest.createTable();
 
    // 判断数据表是否存在
    QString str1 = QString("student");
    qDebug() << "isTabelExist:" <<sqlTest.isTableExist(str1);
 
    // 插入单条数据
    w2dba w2dbaTest1 = {1, "zhangSan", 24};
    w2dba w2dbaTest2 = {2, "lisi", 28};
    sqlTest.singleInsertData(w2dbaTest1);
    sqlTest.singleInsertData(w2dbaTest2);
 
    // 插入多条数据
    QList<w2dba> list;
    w2dba w2dbaTest3 = {3, "liwu", 26};
    w2dba w2dbaTest4 = {4, "niuer", 27};
    list.append(w2dbaTest3);
    list.append(w2dbaTest4);
    sqlTest.moreInsertData(list);
    // 查询全部数据
    sqlTest.queryTable();
    qDebug() << endl;
 
    // 修改数据
    sqlTest.modifyData(2, "modify", 10);
    // 查询全部数据
    sqlTest.queryTable();
    qDebug() << endl;
 
    // 删除数据
    sqlTest.deleteData(2);
    // 查询全部数据
    sqlTest.queryTable();
    qDebug() << endl;
 
    // 删除数据表
    QString str2 = QString("student");
    sqlTest.deleteTable(str2);
 
    //关闭数据库
    sqlTest.closeDb();
 
    return a.exec();
}

操作の結果は次のとおりです。

テーブルが作成されました!
isTabelExist: true
"id:1 name:zhangSan age:24"
"id:2 name:lisi age:28"
"id:3 name:liwu age:26"
"id:4 name:niuer age:27"

データ更新成功!
「id:1 name:zhangSan age:24」
「id:2 name:modify age:10」
「id:3 name:liwu age:26」
「id:4 name:niuer age:27」

データ削除成功!
"id:1 name:zhangSan age:24"
"id:3 name:liwu age:26"
"id:4 name:niuer age:27"

削除されたテーブルの成功

この記事の特典として、 Qt 開発学習教材パッケージ、テクニカル ビデオ (C++ 言語の基礎、C++ デザイン パターン、Q​​t プログラミング入門、QT シグナルとスロット メカニズム、QT インターフェイス開発イメージ図、QT ネットワーク、QT を含む) を無料で受け取ることができます。データベースプログラミング、QTプロジェクト実戦、QSS、OpenCV、Quickモジュール、取材質問等) ↓↓↓↓↓↓下記参照↓↓料金の受け取りは記事下部をクリック↓↓

おすすめ

転載: blog.csdn.net/m0_73443478/article/details/130410956