13,005
回編集
22行目: | 22行目: | ||
<br> | <br> | ||
<u>また、使用時にはエラーハンドリングおよびセキュリティ対策 (SQLインジェクション対策等) を適切に実装することを推奨する。</u><br> | <u>また、使用時にはエラーハンドリングおよびセキュリティ対策 (SQLインジェクション対策等) を適切に実装することを推奨する。</u><br> | ||
* ロギング機能の追加 | |||
* リトライメカニズムの実装 (一時的なネットワーク問題などに対処するため) | |||
* 詳細なエラータイプの定義 (例:接続エラー、クエリエラー等) | |||
* パラメータのバリデーション | |||
* SQLインジェクション対策の強化 | |||
<br> | |||
開発向けMariaDBライブラリをインストールする。<br> | |||
# RHEL | |||
sudo dnf install mariadb-devel | |||
# SUSE | |||
sudo zypper install libmariadbd-devel | |||
<br> | <br> | ||
<syntaxhighlight lang="cmake"> | <syntaxhighlight lang="cmake"> | ||
103行目: | 115行目: | ||
bool deleteRecord(int id); | bool deleteRecord(int id); | ||
QList<QMap<QString, QVariant>> readAllRecords(); | QList<QMap<QString, QVariant>> readAllRecords(); | ||
void beginTransaction(); | |||
void commitTransaction(); | |||
void rollbackTransaction(); | |||
// 複数の操作をトランザクションで実行する場合のメソッド | |||
void performComplexOperation(const QString &name1, int age1, const QString &name2, int age2); | |||
private: | private: | ||
162行目: | 181行目: | ||
QString errorMessage = QString("%1 failed: %2").arg(operation, error.text()); | QString errorMessage = QString("%1 failed: %2").arg(operation, error.text()); | ||
throw DatabaseException(errorMessage); | throw DatabaseException(errorMessage); | ||
} | |||
// トランザクションを開始 | |||
void DatabaseManager::beginTransaction() | |||
{ | |||
checkConnection(); | |||
if (!db.transaction()) { | |||
throw DatabaseException("Failed to start transaction: " + db.lastError().text()); | |||
} | |||
qDebug() << "Transaction started"; | |||
} | |||
// トランザクションをコミット | |||
void DatabaseManager::commitTransaction() | |||
{ | |||
checkConnection(); | |||
if (!db.commit()) { | |||
throw DatabaseException("Failed to commit transaction: " + db.lastError().text()); | |||
} | |||
qDebug() << "Transaction committed"; | |||
} | |||
// トランザクションをロールバック | |||
void DatabaseManager::rollbackTransaction() | |||
{ | |||
checkConnection(); | |||
if (!db.rollback()) { | |||
throw DatabaseException("Failed to rollback transaction: " + db.lastError().text()); | |||
} | |||
qDebug() << "Transaction rolled back"; | |||
} | |||
// 複数の操作を1つのトランザクションとして実行するメソッド | |||
void DatabaseManager::performComplexOperation(const QString &name1, int age1, const QString &name2, int age2) | |||
{ | |||
try { | |||
beginTransaction(); | |||
insertRecord(name1, age1); | |||
insertRecord(name2, age2); | |||
commitTransaction(); | |||
qDebug() << "Complex operation completed successfully"; | |||
} | |||
catch (const DatabaseException& e) { | |||
rollbackTransaction(); | |||
throw DatabaseException("Complex operation failed: " + QString(e.what())); | |||
} | |||
} | } | ||
274行目: | 348行目: | ||
dbManager.createTable(); | dbManager.createTable(); | ||
// | // トランザクションを使用した複雑な操作 | ||
dbManager. | dbManager.performComplexOperation("Alice", 28, "Bob", 32); | ||
dbManager. | |||
// 個別のトランザクション管理の例 | |||
dbManager.beginTransaction(); | |||
try { | |||
// 既存のレコードの更新 | |||
dbManager.updateRecord(1, "John Doe Updated", 31); | |||
// 任意のレコードの削除 | |||
dbManager.deleteRecord(2); | |||
dbManager.commitTransaction(); | |||
} | |||
catch (const DatabaseException& e) { | |||
dbManager.rollbackTransaction(); | |||
qCritical() << "Transaction failed:" << e.what(); | |||
} | |||
// 全てのレコードを読み込む | // 全てのレコードを読み込む | ||
QList<QMap<QString, QVariant>> records = dbManager.readAllRecords(); | QList<QMap<QString, QVariant>> records = dbManager.readAllRecords(); | ||
for (const auto& record : records) { | for (const auto &record : records) { | ||
qDebug() << "ID:" << record["id"].toInt() | |||
<< "Name:" << record["name"].toString() | |||
<< "Age:" << record["age"].toInt(); | |||
} | |||
// 全てのレコードを読み込む | // 全てのレコードを読み込む | ||
records = dbManager.readAllRecords(); | records = dbManager.readAllRecords(); | ||
312行目: | 394行目: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
トランザクションを使用するメリットを以下に示す。<br> | |||
* データの一貫性 | |||
*: 複数の操作を1つの単位として扱うことができる。 | |||
* エラー回復 | |||
*: 問題が発生した場合、簡単に全ての変更を元に戻すことができる。 | |||
* パフォーマンス | |||
*: 多数の操作を一度のトランザクションで行うことにより、データベースとの通信回数を減らし、パフォーマンスを向上させることができる。 | |||
<br> | |||
ただし、トランザクション管理を使用する場合は、以下に示す事柄に注意すること。<br> | |||
* トランザクションは必要な場合にのみ使用して、不必要に長く保持しないようにする。 | |||
* ネストされたトランザクションの扱いには注意が必要である。<br><code>QSQLDatabase</code>クラスは、一般的にネストされたトランザクションをサポートしていない。 | |||
* 大規模なデータ操作を行う場合は、適切なチェックポイントを設定することを検討する。 | |||
<br><br> | <br><br> | ||