はじめに
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が付属しているわけではありません)。
- QDB2-IBM DB2(バージョン7.1以降
- QIBASE-Borland InterBase
- QMYSQL-MySQL
- QOCI-Oracle Call Interfaceドライバー
- QODBC-オープンデータベースコネクティビティ(ODBC)-Microsoft SQL Serverおよびその他のODBC互換データベース
- QPSQL-PostgreSQL(バージョン7.3以降)
- QSQLITE2-SQLiteバージョン2
- QSQLITE-SQLiteバージョン3
- 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 .
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 .
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 .
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 .
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()を呼び出すだけです。 たとえば、次のように:
*このソースコードは、 ソースコードハイライターで強調表示されました。
- QSqlQueryクエリ。
- query.exec( "SELECT name、salary FROM employee WHERE salary> 50000" );
QSqlQueryコンストラクターは、使用するデータベース接続を指定するオプションのQSqlDatabase引数を受け入れます。 指定しない場合、デフォルトの接続が使用されます。
エラーが発生した場合、exec()はfalseを返します。 エラーには、QSqlQuery :: lastError()を使用してアクセスできます。
QSqlQueryは、単一のクエリの結果セットへの1回限りのアクセスを提供します。 exec()が呼び出された後、内部QSqlQueryポインターは最初のレコードの前の位置を指します。 QSqlQuery :: next()メソッドを1回呼び出すと、ポインターが最初のレコードに移動します。 この後、次の()呼び出しを繰り返して、falseが返されるまで他のエントリにアクセスする必要があります。 すべてのレコードを順番に処理する典型的なループを次に示します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- while (query.next()){
- QString名=クエリ。 値 (0).toString();
- int salary = query。 値 (1).toInt();
- qDebug()<< name << salary;
- }
QSqlQueryはSELECTだけでなく、他のクエリも実行できます。 次の例では、INSERTを使用してレコードをテーブルに挿入します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- QSqlQueryクエリ。
- query.exec( "INSERT INTO employee(id、name、salary)"
- 「VALUES(1001、 'Thad Beaumont'、65000)」 );
多くのレコードを同時に挿入する必要がある場合は、実際の挿入値からリクエストを分離する方が効率的です。 これは、パラメーターを介して値を挿入することで実行できます。 Qtは、名前付きパラメーターと位置パラメーターの2つの値挿入構文をサポートしています。 次の例は、名前付きパラメーターを使用した挿入を示しています。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- QSqlQueryクエリ。
- query.prepare( "INSERT INTO employee(id、name、salary)"
- "VALUES(:id ,: name ,: salary)" );
- query.bindValue( ":id" 、1001);
- query.bindValue( ":name" 、 "Thad Beaumont" );
- query.bindValue( ":salary" 、65000);
- query.exec();
この例は、位置パラメーターを使用した挿入を示しています。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- QSqlQueryクエリ。
- query.prepare( "INSERT INTO employee(id、name、salary)"
- "VALUES(?、?、?)" );
- query.addBindValue(1001);
- query.addBindValue( "Thad Beaumont" );
- query.addBindValue(65000);
- query.exec();
複数のレコードを挿入するときは、QSqlQuery :: prepare()を一度だけ呼び出す必要があります。 次に、bindValue()またはaddBindValue()を呼び出してから、必要な回数だけexec()を呼び出します。
テーブルビューでデータを表示する
QSqlQueryModel、QSqlTableModel、およびQSqlRelationalTableModelクラスは、QListView、QTableView、QTreeViewなどのQtビュークラスのデータソースとして使用できます。 実際には、結果として得られるSQL選択が本質的に2次元のデータ構造であるという事実により、QTableViewが最も頻繁に使用されます。
次の例では、SQLデータモデルに基づいてビューを作成します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- QSqlTableModelモデル;
- model.setTable( "employee" );
- QTableView * view = 新しい QTableView;
- view-> setModel(&model);
- view-> show();
モデルが読み取り/書き込みモデル(QSqlTableModelなど)の場合、ビューを使用してフィールドを編集できます。 これは、次のコードを使用して無効にすることができます
*このソースコードは、 ソースコードハイライターで強調表示されました。
- view-> setEditTriggers(QAbstractItemView :: NoEditTriggers);
同じモデルを複数のビューのデータソースとして使用できます。 ユーザーがビューの1つを使用してモデルデータを変更すると、他のビューにはすぐに変更が表示されます。
上部の列を示すプレゼンテーションクラスは、ヘッダーを表示します。 タイトルテキストを変更するには、モデルのsetHeaderData()関数を使用します。 例:
*このソースコードは、 ソースコードハイライターで強調表示されました。
- model-> setHeaderData(0、Qt :: Horizontal、QObject :: tr( "ID" ));
- model-> setHeaderData(1、Qt :: Horizontal、QObject :: tr( "Name" ));
- model-> setHeaderData(2、Qt :: Horizontal、QObject :: tr( "City" ));
- model-> setHeaderData(3、Qt :: Horizontal、QObject :: tr( "Country" ));
おわりに
この記事では、Qtでデータベースを使用する際の基本的な原則について説明します。 ただし、ここで示した可能性に加えて、たとえば、トランザクション、外部キーの操作、データ指向のフォームの作成など、多くの興味深いことがあります。 残念ながら、これらのトピックは1つの記事としては十分に広範です。
UPD:コードのエラーを修正しました。