본문 바로가기
C++ GUI

C++ GUI : MFC에서 matiaDB ODBC 사용하기

by taekho 2026. 5. 8.

 

1. mariaDB ODBC 설치는 다음을 참고하세요.

https://taekho.tistory.com/28

 

C++ : matiaDB ODBC 설치하기

1. mariaDB Server ODBC Driver를 설치한다.https://mariadb.com/downloads/connectors/ Download MariaDB Products & Tools | MariaDBDownload MariaDB products, connectors, and tools including Community Server, Enterprise Server, ColumnStore and MaxScale.mari

taekho.tistory.com

 

2. [MFC앱] 프로젝트를 만든다.

 

3. [애플리케이션 종류]를 아래와 같이 선택한다.

 

4.[생성된 클래스]를 아래와 같이 선택 및 수정하고 [마침]버튼을 누른다.

 

5. framework.h 파일에 #include <afxdb.h>을 추가한다.

 

6. DTO(Data Transfer Object)를 추가한다.

 

6.1 MemberDTO.h 파일을 추가하다.

#pragma once

class MemberDTO
{
public:

    int id = 0;

    CString forename;
    CString surname;
    CString email;
};

 

7. DAO(Data Access Object))를 추가한다.

 

7.1 MemberDAO.h 파일을 추가한다.

#pragma once

#include <vector>

#include "MemberDTO.h"

class MemberDAO
{
private:

    CDatabase m_db;

public:

    MemberDAO();

    ~MemberDAO();

    BOOL Connect();

    void Disconnect();

    BOOL Insert(MemberDTO& dto);

    BOOL Update(MemberDTO& dto);

    BOOL Delete(int id);

    MemberDTO SelectById(int id);

    std::vector<MemberDTO> SelectAll();

    int GetLastInsertId();

private:
    CString Escape(const CString& str);
};

 

7.2 MemberDAO.cpp 파일을 추가한다

#include "pch.h"
#include "MemberDAO.h"

MemberDAO::MemberDAO()
{
    //Connect();
}

MemberDAO::~MemberDAO()
{
    Disconnect();
}

BOOL MemberDAO::Connect()
{
    if (m_db.IsOpen())
        return TRUE;

    return m_db.OpenEx(_T("DSN=MyMariaDB"), CDatabase::noOdbcDialog);
}

void MemberDAO::Disconnect()
{
    if (m_db.IsOpen())
    {
        m_db.Close();
    }
}

BOOL MemberDAO::Insert(MemberDTO& dto)
{
    TRY
    {
        CString sql;

        sql.Format(
            _T("INSERT INTO member ")
            _T("(forename,surname,email) VALUES ('%s','%s','%s')"),
            (LPCTSTR)Escape(dto.forename), (LPCTSTR)Escape(dto.surname), (LPCTSTR)Escape(dto.email)
        );

        m_db.ExecuteSQL(sql);

        return TRUE;
    }
        CATCH(CDBException, e)
    {
        AfxMessageBox(e->m_strError);

        return FALSE;
    }
    END_CATCH
}

BOOL MemberDAO::Update(MemberDTO& dto)
{
    TRY
    {
        CString sql;

        sql.Format(
            _T("UPDATE member SET forename='%s', surname='%s', email='%s' WHERE id=%d"),
            (LPCTSTR)Escape(dto.forename), (LPCTSTR)Escape(dto.surname),
            (LPCTSTR)Escape(dto.email),dto.id
        );

        m_db.ExecuteSQL(sql);

        return TRUE;
    }
        CATCH(CDBException, e)
    {
        AfxMessageBox(e->m_strError);

        return FALSE;
    }
    END_CATCH
}

BOOL MemberDAO::Delete(int id)
{
    TRY
    {
        CString sql;

        sql.Format(
            _T("DELETE FROM member WHERE id=%d"),
            id);

        m_db.ExecuteSQL(sql);

        return TRUE;
    }
        CATCH(CDBException, e)
    {
        AfxMessageBox(e->m_strError);

        return FALSE;
    }
    END_CATCH
}

std::vector<MemberDTO>
MemberDAO::SelectAll()
{
    std::vector<MemberDTO> list;

    CRecordset rs(&m_db);

    rs.Open(
        CRecordset::forwardOnly,
        _T("SELECT * FROM member"));

    while (!rs.IsEOF())
    {
        MemberDTO dto;

        CString str;

        rs.GetFieldValue(_T("id"), str);
        dto.id = _ttoi(str);

        rs.GetFieldValue(_T("forename"), dto.forename);
        rs.GetFieldValue(_T("surname"), dto.surname);
        rs.GetFieldValue(_T("email"), dto.email);
        rs.GetFieldValue(_T("password"), dto.password);
        rs.GetFieldValue(_T("joined"), dto.joined);
        rs.GetFieldValue(_T("picture"), dto.picture);

        list.push_back(dto);

        rs.MoveNext();
    }

    rs.Close();

    return list;
}

int MemberDAO::GetLastInsertId()
{
    CRecordset rs(&m_db);

    rs.Open(
        CRecordset::forwardOnly,
        _T("SELECT LAST_INSERT_ID()"));

    CString str;

    rs.GetFieldValue((short)0, str);

    rs.Close();

    return _ttoi(str);
}

MemberDTO MemberDAO::SelectById(int id)
{
    MemberDTO dto;

    TRY
    {
        CString sql;

        sql.Format(
            _T("SELECT id, forename, surname, email")
            _T("FROM member WHERE id=%d"), id);

        CRecordset rs(&m_db);

        rs.Open(CRecordset::forwardOnly,sql);

        if (!rs.IsEOF())
        {
            CString str;

            rs.GetFieldValue(_T("id"),str);

            dto.id = _ttoi(str);

            rs.GetFieldValue(_T("forename"),dto.forename);
            rs.GetFieldValue(_T("surname"),dto.surname);
            rs.GetFieldValue(_T("email"),dto.email);
            rs.GetFieldValue(_T("password"),dto.password);
            rs.GetFieldValue(_T("joined"),dto.joined);
            rs.GetFieldValue(_T("picture"),dto.picture);
        }

        rs.Close();
    }
        CATCH(CDBException, e)
    {
        AfxMessageBox(e->m_strError);
    }
    END_CATCH

        return dto;
}

CString MemberDAO::Escape(const CString& str)
{
    CString result = str;

    result.Replace(_T("'"), _T("''"));

    return result;
}

 

8. [폼 디자이너]로 리스트 컨트롤(CListCtrl) 과 추가 버튼(CButton)을 추가한다.

 

9. 프로젝트를 선택 후 우클릭하여 [클래스 마법사]를 선택한다.

 

10.리스트 컨트롤과 추가 버튼을 멤버변수로 추가한다.

 

10.1 [명령]탭에서 버튼 클릭 이벤트 처리기를 추가한다.

 

11.리스트 컨트롤 초기화 하는 함수 InitList()함수를 추가한다.

void CMainView::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	InitList();

	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
}

void CMainView::InitList()
{
	// TODO: 여기에 구현 코드 추가.
	DWORD style = m_listCtrl.GetExtendedStyle();

	m_listCtrl.SetExtendedStyle(style | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_listCtrl.ModifyStyle(0, LVS_REPORT);

	m_listCtrl.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);

	m_listCtrl.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 50);
	m_listCtrl.InsertColumn(1, _T("Forename"), LVCFMT_LEFT, 100);
	m_listCtrl.InsertColumn(2, _T("Surname"), LVCFMT_LEFT, 100);
	m_listCtrl.InsertColumn(3, _T("Email"), LVCFMT_LEFT, 150);

	LoadMembers();
}

 

12. LoadMembers()함수를 추가한다.

void CMainView::LoadMembers()
{
	// TODO: 여기에 구현 코드 추가.
	MemberDAO dao;

	if (!dao.Connect())
	{
		AfxMessageBox(_T("MariaDB 연결 실패"));
		return;
	}

	std::vector<MemberDTO> members = dao.GetAllMembers();

	m_listCtrl.DeleteAllItems();

	int i = 0;
	for(auto& m : members)
	{
		m_listCtrl.InsertItem(i, m.id);
		m_listCtrl.SetItemText(i, 1, m.forename);
		m_listCtrl.SetItemText(i, 2, m.surname);
		m_listCtrl.SetItemText(i, 3, m.email);
		i++;
	}

}

 

13. 프로젝트를 실행시키면 결과를 확인할 수 있다.

 

14. mariaDB에 데이터를 insert하기 위해서 다음 절차에 따라 코드를 추가한다.

 

15. [폼 디자이너]로 에디터 컨트롤(CEditCtrl)를 4개 추가한다.(ID, ForeName, SurName, Email)

 

16. [클래스 마법사]로 에디터 컨트롤들을 멤버변수 등록한다.

 

17. CMainView::OnClickedButtonAdd()함수에 아래와 같이 추가한다.

void CMainView::OnClickedButtonAdd()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	MemberDAO dao;

	if(!dao.Connect())
	{
		AfxMessageBox(_T("MariaDB 연결 실패"));
		return;
	}	

	MemberDTO dto;

	CString text;
	m_editForeName.GetWindowText(text);
	dto.forename = text;
	m_editSurName.GetWindowText(text);
	dto.surname = text;
	m_editEmail.GetWindowText(text);
	dto.email = text;

	if(dao.Insert(dto))
	{
		LoadMembers();
	}
	else
	{
		AfxMessageBox(_T("회원 추가 실패"));
	}

	dao.Disconnect();
	
}

 

18. 프로젝트를 실행하면 데이터 베이스에 insert 된 것을 확인 가능하다.

 

* 참고

- DSN 설정 없이 앱에서 실행하는 것도 가능하다.

- MemberDAO.cpp 파일의 Connect()함수를 수정하면된다.

BOOL MemberDAO::Connect()
{
    if (m_db.IsOpen())
        return TRUE;

    CString conn;

    conn =
        _T("DRIVER={MariaDB ODBC 3.2 Driver};")
        _T("SERVER=127.0.0.1;")
        _T("PORT=3306;")
        _T("DATABASE=database1;")
        _T("UID=user1;")
        _T("PWD=password1;")
        _T("CHARSET=utf8mb4;");

    return m_db.OpenEx(conn,CDatabase::noOdbcDialog);

    //return m_db.OpenEx(_T("DSN=MyMariaDB"), CDatabase::noOdbcDialog);
}