MFCで物品購入承認システム作成 3

前回までの話。

MFCで物品購入承認システム作成 1

MFCで物品購入承認システム作成 2

スキーマ・テーブル作成

今回はまず、いったん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とパスワードが登録されているものか確認する作業をしていきます。

今回はここまで。

MFCで物品購入承認システム作成 4
前回までの話。MFCで物品購入承認システム作成 1MFCで物品購入承認システム作成 2MFCで物品購入承認システム作成 3ログインチェック作成いよいよユーザテーブルからログイン可否の判断を行おうと思います。まず準備として、手動でテーブルにデ...

コメント

タイトルとURLをコピーしました