Qtの基礎 - データベース
ナビゲーションに移動
検索に移動
概要
MariaDB
以下の例では、MariaDBのデータベースを使用して、以下に示すようなテーブルを作成して基本的なCRUD操作を行っている。
実務では、必要に応じてフィールドを追加、または、データ型や制約を調整したりする必要がある。
- テーブル名
- people
- id
- INT型
- 制約 1 : AUTO_INCREMENT
- 制約 2 : PRIMARY KEY
- 各レコードを一意に識別するための自動増分の主キー。
- name
- VARCHAR(40)型
- 制約 : NOT NULL
- 名前を格納するフィールドで、最大40文字まで保存可能。
- age
- INT型
- 年齢を格納する整数型のフィールド。
また、使用時にはエラーハンドリングおよびセキュリティ対策 (SQLインジェクション対策等) を適切に実装することを推奨する。
# CMakeLists.txtファイル
cmake_minimum_required(VERSION 3.21)
project(QtMariaDBProject LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Sql)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Sql)
# MariaDB Connector/Cを検索
find_path(MARIADB_INCLUDE_DIR mysql.h
/usr/include/mysql
)
find_library(MARIADB_LIBRARY NAMES mariadb
PATHS
/usr/lib
/usr/lib64
)
if(NOT MARIADB_INCLUDE_DIR OR NOT MARIADB_LIBRARY)
message(FATAL_ERROR "MariaDB Connector/C not found!")
endif()
add_executable(QtMariaDBProject
main.cpp
DataBaseManager.h
DataBaseManager.cpp
)
# QtライブラリとMariaDBライブラリをリンク
target_link_libraries(QtMariaDBProject PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Sql
${MARIADB_LIBRARY}
)
# MariaDBのヘッダファイルのディレクトリを追加
target_include_directories(QtMariaDBProject PRIVATE
${MARIADB_INCLUDE_DIR}
)
// DataBaseManager.hファイル
#include <QtSql>
#include <QDebug>
class DatabaseManager
{
public:
DatabaseManager();
~DatabaseManager();
bool openConnection();
void closeConnection();
bool createTable();
bool insertRecord(const QString &name, int age);
bool updateRecord(int id, const QString &name, int age);
bool deleteRecord(int id);
void readAllRecords();
private:
QSqlDatabase db;
};
// DataBaseManager.cppファイル
#include "DataBaseManager.h"
DatabaseManager::DatabaseManager()
{
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("<ホスト名またはIPアドレス 例: localhost>");
db.setDatabaseName("<データベース名 例: sampledb>");
db.setUserName("<データベースのユーザ名>");
db.setPassword("<データベースのユーザ名のパスワード>");
}
DatabaseManager::~DatabaseManager()
{
closeConnection();
}
// データベースの接続
bool DatabaseManager::openConnection()
{
if (!db.open()) {
qDebug() << "Error: connection with database failed";
return false;
}
else {
qDebug() << "Database: connection ok";
return true;
}
}
// データベースの切断
void DatabaseManager::closeConnection()
{
db.close();
}
// テーブルの作成
bool DatabaseManager::createTable()
{
QSqlQuery query;
query.prepare("CREATE TABLE IF NOT EXISTS people (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(40) NOT NULL, age INT)");
if (!query.exec()) {
qDebug() << "Error creating table:" << query.lastError().text();
return false;
}
return true;
}
// 単一のレコードの追加
bool DatabaseManager::insertRecord(const QString& name, int age)
{
QSqlQuery query;
query.prepare("INSERT INTO people (name, age) VALUES (:name, :age)");
query.bindValue(":name", name);
query.bindValue(":age", age);
if (!query.exec()) {
qDebug() << "Error inserting record:" << query.lastError().text();
return false;
}
return true;
}
// 単一のレコードの更新
bool DatabaseManager::updateRecord(int id, const QString& name, int age)
{
QSqlQuery query;
query.prepare("UPDATE people SET name = :name, age = :age WHERE id = :id");
query.bindValue(":id", id);
query.bindValue(":name", name);
query.bindValue(":age", age);
if (!query.exec()) {
qDebug() << "Error updating record:" << query.lastError().text();
return false;
}
return true;
}
bool DatabaseManager::deleteRecord(int id)
{
QSqlQuery query;
query.prepare("DELETE FROM people WHERE id = :id");
query.bindValue(":id", id);
if (!query.exec()) {
qDebug() << "Error deleting record:" << query.lastError().text();
return false;
}
return true;
}
// 全てのレコードを読み込む
void DatabaseManager::readAllRecords()
{
QSqlQuery query("SELECT * FROM people");
while (query.next()) {
int id = query.value(0).toInt();
QString name = query.value(1).toString();
int age = query.value(2).toInt();
qDebug() << "ID:" << id << "Name:" << name << "Age:" << age;
}
}
// main.cppファイル
int main()
{
DatabaseManager dbManager;
if (dbManager.openConnection()) {
// テーブルの作成
dbManager.createTable();
// レコードの追加
dbManager.insertRecord("John Doe", 30);
dbManager.insertRecord("Jane Smith", 25);
// 全てのレコードを読み込む
dbManager.readAllRecords();
// 既存のレコードの更新
dbManager.updateRecord(1, "John Doe Updated", 31);
// 任意のレコードの削除
dbManager.deleteRecord(2);
// 全てのレコードを読み込む
dbManager.readAllRecords();
// データーベースを切断
dbManager.closeConnection();
}
return 0;
}
SQLite3
Qtを使用してSQLite3のテーブルにアクセスする場合、まず、QSqlDatabase
クラスを使用してデータベースに接続する。
#include <QSqlDatabase>
#include <QSqlQuery>
// SQLiteデータベースに接続する
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("<SQLiteデータベース名>.sqlite"); // データベースファイル名
if (!db.open())
{
qDebug() << "データベースに接続できませんでした。";
return;
}
次に、QSqlQuery
クラスを使用してクエリを実行する。
以下の例では、テーブルのデータを取得している。
QSqlQuery query;
query.prepare("SELECT * FROM <SQLiteデータベースのテーブル名>");
if (query.exec())
{
while (query.next())
{ // レコードの処理
QString column1 = query.value(0).toString(); // 1番目の列
QString column2 = query.value(1).toString(); // 2番目の列
// 他の列も同様に取得できる
}
}
else
{
qDebug() << "クエリの実行に失敗しました.";
}
// データベース接続を閉じる
db.close();
SQLインジェクション対策
SQLインジェクション対策では、プレースホルダを使用してクエリを構築することが重要である。
以下の例では、":username"がプレースホルダとなり、ユーザからの入力等が直接クエリに組み込まれることなく、安全にクエリが実行される。
また、ユーザからの入力をクエリに組み込む場合、入力データを適切にサニタイズしてクエリに含めるようにすることにより、悪意のあるSQLコードが挿入されても実行されないようにする。
QSqlQuery query;
QString username = "user_input"; // ユーザからの入力等
// プレースホルダを使用して安全にクエリを構築
query.prepare("SELECT * FROM users WHERE username = :username");
query.bindValue(":username", username);
if (query.exec())
{
while (query.next())
{ // レコードの処理
// ...略
}
}
else
{
qDebug() << "クエリの実行に失敗しました.";
}