前回までの話。
スキーマ・テーブル作成
今回はまず、いったんVisual Studioは置いておきます。
同じことを以前やったので、今回はキャプチャの量は少なめで。
MySQL Workbenchを開きます。
スキーマを作成するために、Create a new schema in the connected serverを選択。
スキーマ名はsupply_requestにしておきます。

問題なければ、右下のApplyで作成します。
新スキーマが作られたのを確認できます。

続いてテーブル作成です。
必要なテーブルは「ユーザ」「グループ」「項目」「履歴」の4つです。
ユーザテーブル
作成したsupply_requestのTableを右クリックし、Create Tableを選択します。
作成するユーザテーブル情報はこんな感じ。

- ID : ユーザID。主キーであり、一意です。
Zero fillはソース側で制御しますが、念のため。 - Name : ユーザ名。半角英数字です。
- Password : ユーザパスワード。
後述(多分次回)しますが、ここには20桁くらいの数字が入ってきます。 - Authority : 管理者権限があるかないか。
1=管理者ユーザ、0=一般ユーザです。
これでApply。

ユーザテーブルが作成されました。
グループテーブル
同じ要領でどんどん追加します。
テーブル名はgroup。

- Id : グループID。主キーです。
- Name : グループ名。こちらも半角英数字。
項目テーブル
テーブル名はkoumoku。

- Id : 項目ID。主キーです。
- Name : 項目名。こちらも半角英数字。
- GroupId : どのグループに入っているか。
- Price : その項目の値段です。VARCHARにしています。
履歴テーブル
テーブル名はrecordに。
historyやlogとどれがいいのか迷います…。

- Id : 単なる連番IDです。
- UserId : 申請したユーザのID。
- KoumokuId : ユーザが申請した項目ID。
項目テーブルからグループは自動的にわかります。 - Approval : 0は申請中、1は管理者から承認、2は拒否されたと意味します。
Applyを押して反映させます。
MySQLからデータ取得準備
Visual Studioに戻ります。
今回、色々なところでSQLの処理を行うので、
SQLに関する処理は同じソース内にまとめることにします。
プロジェクトメニューから、クラスの追加を選択します。

ここで新しくクラスやファイル名を決めます。
今回はCMySQLManagerクラスにします。

MySQLManager.hができるので、開いて定数や関数を宣言しておきます。
#pragma once
#include <mysql/jdbc.h>
class CMySQLManager
{
private:
// DB接続関連
const sql::SQLString HOST = "tcp://127.0.0.1:3306";
const sql::SQLString USER = "root";
const sql::SQLString PASSWORD = "password"; //自分の接続パスワード
//スキーマ
const sql::SQLString SCHEMA = "supply_request";
//テーブル
const sql::SQLString TABLE_USER = "user";
const sql::SQLString TABLE_GROUP = "group";
const sql::SQLString TABLE_KOUMOKU = "koumoku";
const sql::SQLString TABLE_RECORD = "record";
// 接続状況
std::shared_ptr<sql::Connection> m_con;
public:
// コンストラクタ
CMySQLManager();
// デストラクタ
~CMySQLManager();
//接続
std::shared_ptr<sql::Connection> GetConnection();
private:
// エラーひとまとめ
void ErrSQLException(sql::SQLException& e);
// CString→SQLString変換処理
sql::SQLString strConverter(CString str);
// UTF8→UTF16変換処理
CString strConvertFromUTF8ToUTF16(sql::SQLString strCol);
};2行目をincludeは必須です。
18行目までは色々定数を宣言。
21行目は、一度オブジェクトを作ると何度も接続を試みないよう、
メンバ変数で接続状況を保持しておきます。
後はコンストラクタ・デストラクタと、
接続を行う関数、
エラー関連の関数、
今後たくさん使う変換処理を2つ作っておきます。
では、MySQLManager.cppの方で処理を書き始めます。
まずはコンストラクタ、デストラクタ。
#include "pch.h"
#include "SupplyRequestManager.h"
#include "MySQLManager.h"
/**
* @fn
* @brief コンストラクタ
* @param なし
* @return なし
*/
CMySQLManager::CMySQLManager()
{
}
/**
* @fn
* @brief デストラクタ
* @param なし
* @return なし
*/
CMySQLManager::~CMySQLManager()
{
// デストラクタで接続をクローズ
if (m_con && m_con->isClosed() == false)
{
m_con->close();
}
}コンストラクタでは特に何もしません。
必要がありそうなら別途追記します。
デストラクタでは、接続クローズ処理です。
続いて、処理の補助をしてくれる関数3つ。
/**
* @fn
* @brief エラー関連処理
* @param SQLException& e エラー情報
* @return なし
*/
void CMySQLManager::ErrSQLException(sql::SQLException& e)
{
//接続できなかったため、エラーを表示させる
CString errorMessage = _T("");
errorMessage.Format(_T("エラー: %s\r\nエラーコード: %d"), CString(e.what()), e.getErrorCode());
AfxMessageBox(errorMessage, MB_OK | MB_ICONERROR);
}
/**
* @fn
* @brief SQLString変換処理
* @param CString str 変換前
* @return SQLString 変換後
*/
sql::SQLString CMySQLManager::strConverter(CString str)
{
CT2CA pszConvertedAnsiString(str);
std::string strStd(pszConvertedAnsiString);
sql::SQLString sqlStrUserID(strStd);
return sqlStrUserID;
}
/**
* @fn
* @brief テーブルから取得したデータをUTF16に変換
* @param SQLString strCol 変換前
* @return CString 変換後
*/
CString CMySQLManager::strConvertFromUTF8ToUTF16(sql::SQLString strCol)
{
CString strRtn = _T("");
int len = MultiByteToWideChar(CP_UTF8, 0, strCol.c_str(), -1, NULL, 0);
if (len > 0)
{
std::wstring wideName(len, 0);
MultiByteToWideChar(CP_UTF8, 0, strCol.c_str(), -1, &wideName[0], len);
// std::wstringからCStringに変換
CString cstrCol(wideName.c_str());
strRtn = cstrCol;
}
return strRtn;
}まぁ特記することはないかなぁと。
単なる変換と、メッセージ出してるだけです。
今回は変換処理は使いませんが、次回以降たくさんこれらは使います。
最後に、重要な役割GetConnection。
/**
* @fn
* @brief MySQL接続処理
* @param なし
* @return m_con
*/
std::shared_ptr<sql::Connection> CMySQLManager::GetConnection()
{
if (!m_con || m_con->isClosed())
{
try
{
sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
// 新しい接続を作成
m_con = std::shared_ptr<sql::Connection>(driver->connect(HOST, USER, PASSWORD));
}
catch (sql::SQLException& e)
{
// 接続でエラーが生じた
ErrSQLException(e);
}
}
return m_con;
}接続が確立されていればif文内には入りませんが、
されていなければ、新しく接続を試みます。
以上が、最初に作っておきたい処理です。
これらを使って、次回はログイン機能を動かしてみようと思います。
終わりに
今回は実際にテーブルを作ったのと、
MySQLへ繋ぐための処理&補助処理を作成しました。
次回はユーザテーブルからSELECTし、
IDとパスワードが登録されているものか確認する作業をしていきます。
今回はここまで。

コメント