Qtでデータベースを操作する

Qtでは、標準DBMSを使用してプラットフォームに依存しないデータベースアプリケーションを作成できます。 Qtには、Oracle、Microsoft SQL Server、Sybase Adaptive Server、IBM DB2、PostgreSQL、MySQL、およびODBC互換データベース用のネイティブドライバーが含まれています。 Qtにはデータベース固有のウィジェットが含まれており、組み込みまたは個別に作成されたウィジェットのデータベースを操作するための拡張機能もサポートしています。



はじめに



Qtでのデータベースの操作は、さまざまなレベルで行われます。

1.Layerドライバー-QSqlDriver、QSqlDriverCreator、QSqlDriverCreatorBase、QSqlDriverPlugin、およびQSqlResultクラスが含まれています。 この層は、特定のデータベースとSQL API層の間の低レベルのブリッジを提供します。

2.Layer SQL API-このレイヤーはデータベースへのアクセスを提供します。 接続は、QSqlDatabaseクラスを使用して確立されます。 データベースとの対話は、QSqlQueryクラスを使用して実行されます。 QSqlDatabaseクラスとQSqlQueryクラスに加えて、SQL APIレイヤーはQSqlError、QSqlField、QSqlIndex、およびQsqlRecordクラスに依存しています。

3.ユーザーインターフェイスレイヤー-このレイヤーは、データベースのデータをデータ指向のウィジェットに関連付けます。 これには、QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModelなどのクラスが含まれます。



データベース接続



QSqlQueryとQSqlQueryModelを使用してデータベースにアクセスするには、1つ以上のデータベース接続を作成して開く必要があります。

Qtは次のデータベースで動作します(GPLライセンスとの非互換性のため、すべてのプラグインにQt Open Source Editionが付属しているわけではありません)。

  1. QDB2-IBM DB2(バージョン7.1以降
  2. QIBASE-Borland InterBase
  3. QMYSQL-MySQL
  4. QOCI-Oracle Call Interfaceドライバー
  5. QODBC-オープンデータベースコネクティビティ(ODBC)-Microsoft SQL Serverおよびその他のODBC互換データベース
  6. QPSQL-PostgreSQL(バージョン7.3以降)
  7. QSQLITE2-SQLiteバージョン2
  8. QSQLITE-SQLiteバージョン3
  9. QTDS-Sybase Adaptive Serverドライバー


Qtの配信に含まれていないドライバープラグインをビルドするには、使用するDBMSに適切なクライアントライブラリが必要です。



次のようにデータベースに接続できます。

QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



  1. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



  2. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



  3. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



  4. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



  5. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



  6. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .



QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" ); db.setHostName( "bigblue" ); db.setDatabaseName( "flightdb" ); db.setUserName( "acarlson" ); db.setPassword( "1uTbSbAs" ); bool ok = db.open(); * This source code was highlighted with Source Code Highlighter .





最初の行は接続オブジェクトを作成し、最後の行はそれを開きます。 この間隔では、接続名、データベース名、ホスト名、ユーザー名、パスワードなどの一部の接続情報が初期化されます。 この例では、bigblueノードのflightdb MySQLデータベースに接続します。 addDatabase()の引数「QMYSQL」は、接続に使用するデータベースドライバーのタイプを示し、「mydb」は接続の名前です。

接続が確立されると、プログラムの任意の場所から静的関数QSqlDatabase :: database()を接続の名前で呼び出して、この接続へのポインターを取得できます。 接続名を渡さない場合、デフォルトで接続が返されます。

open()が失敗すると、falseを返します。 この場合、QSqlDatabase :: lastError()を呼び出すことでエラー情報を取得できます。

データベースへの接続を削除するには、最初にQSqlDatabase :: close()を使用してデータベースを閉じ、次に静的メソッドQSqlDatabase :: removeDatabase()を使用して接続を削除する必要があります。



SQLステートメントの実行



QSqlQueryクラスは、SQLクエリを実行し、結果セットをナビゲートするためのインターフェイスを提供します。

SQLクエリを実行するには、QSqlQueryオブジェクトを作成してQSqlQuery :: exec()を呼び出すだけです。 たとえば、次のように:





  1. QSqlQueryクエリ。
  2. query.exec( "SELECT name、salary FROM employee WHERE salary> 50000" );
*このソースコードは、 ソースコードハイライターで強調表示されました。


QSqlQueryコンストラクターは、使用するデータベース接続を指定するオプションのQSqlDatabase引数を受け入れます。 指定しない場合、デフォルトの接続が使用されます。

エラーが発生した場合、exec()はfalseを返します。 エラーには、QSqlQuery :: lastError()を使用してアクセスできます。

QSqlQueryは、単一のクエリの結果セットへの1回限りのアクセスを提供します。 exec()が呼び出された後、内部QSqlQueryポインターは最初のレコードの前の位置を指します。 QSqlQuery :: next()メソッドを1回呼び出すと、ポインターが最初のレコードに移動します。 この後、次の()呼び出しを繰り返して、falseが返されるまで他のエントリにアクセスする必要があります。 すべてのレコードを順番に処理する典型的なループを次に示します。





  1. while (query.next()){
  2. QString名=クエリ。 (0).toString();
  3. int salary = query。 (1).toInt();
  4. qDebug()<< name << salary;
  5. }
*このソースコードは、 ソースコードハイライターで強調表示されました。


QSqlQueryはSELECTだけでなく、他のクエリも実行できます。 次の例では、INSERTを使用してレコードをテーブルに挿入します。





  1. QSqlQueryクエリ。
  2. query.exec( "INSERT INTO employee(id、name、salary)"
  3. 「VALUES(1001、 'Thad Beaumont'、65000)」 );
*このソースコードは、 ソースコードハイライターで強調表示されました。


多くのレコードを同時に挿入する必要がある場合は、実際の挿入値からリクエストを分離する方が効率的です。 これは、パラメーターを介して値を挿入することで実行できます。 Qtは、名前付きパラメーターと位置パラメーターの2つの値挿入構文をサポートしています。 次の例は、名前付きパラメーターを使用した挿入を示しています。





  1. QSqlQueryクエリ。
  2. query.prepare( "INSERT INTO employee(id、name、salary)"
  3. "VALUES(:id ,: name ,: salary)" );
  4. query.bindValue( ":id" 、1001);
  5. query.bindValue( ":name""Thad Beaumont" );
  6. query.bindValue( ":salary" 、65000);
  7. query.exec();
*このソースコードは、 ソースコードハイライターで強調表示されました。


この例は、位置パラメーターを使用した挿入を示しています。





  1. QSqlQueryクエリ。
  2. query.prepare( "INSERT INTO employee(id、name、salary)"
  3. "VALUES(?、?、?)" );
  4. query.addBindValue(1001);
  5. query.addBindValue( "Thad Beaumont" );
  6. query.addBindValue(65000);
  7. query.exec();
*このソースコードは、 ソースコードハイライターで強調表示されました。


複数のレコードを挿入するときは、QSqlQuery :: prepare()を一度だけ呼び出す必要があります。 次に、bindValue()またはaddBindValue()を呼び出してから、必要な回数だけexec()を呼び出します。



テーブルビューでデータを表示する



QSqlQueryModel、QSqlTableModel、およびQSqlRelationalTableModelクラスは、QListView、QTableView、QTreeViewなどのQtビュークラスのデータソースとして使用できます。 実際には、結果として得られるSQL選択が本質的に2次元のデータ構造であるという事実により、QTableViewが最も頻繁に使用されます。

次の例では、SQLデータモデルに基づいてビューを作成します。





  1. QSqlTableModelモデル;
  2. model.setTable( "employee" );
  3. QTableView * view = 新しい QTableView;
  4. view-> setModel(&model);
  5. view-> show();
*このソースコードは、 ソースコードハイライターで強調表示されました。


モデルが読み取り/書き込みモデル(QSqlTableModelなど)の場合、ビューを使用してフィールドを編集できます。 これは、次のコードを使用して無効にすることができます





  1. view-> setEditTriggers(QAbstractItemView :: NoEditTriggers);
*このソースコードは、 ソースコードハイライターで強調表示されました。


同じモデルを複数のビューのデータソースとして使用できます。 ユーザーがビューの1つを使用してモデルデータを変更すると、他のビューにはすぐに変更が表示されます。

上部の列を示すプレゼンテーションクラスは、ヘッダーを表示します。 タイトルテキストを変更するには、モデルのsetHeaderData()関数を使用します。 例:





  1. model-> setHeaderData(0、Qt :: Horizo​​ntal、QObject :: tr( "ID" ));
  2. model-> setHeaderData(1、Qt :: Horizo​​ntal、QObject :: tr( "Name" ));
  3. model-> setHeaderData(2、Qt :: Horizo​​ntal、QObject :: tr( "City" ));
  4. model-> setHeaderData(3、Qt :: Horizo​​ntal、QObject :: tr( "Country" ));
*このソースコードは、 ソースコードハイライターで強調表示されました。




おわりに



この記事では、Qtでデータベースを使用する際の基本的な原則について説明します。 ただし、ここで示した可能性に加えて、たとえば、トランザクション、外部キーの操作、データ指向のフォームの作成など、多くの興味深いことがあります。 残念ながら、これらのトピックは1つの記事としては十分に広範です。



UPD:コードのエラーを修正しました。



All Articles