본문 바로가기
C++ GUI

C++ GUI : MFC에서 mariaDB C/C++ Connector 사용하기

by taekho 2026. 5. 8.

 

 

1. mariaDB C/C++ Connector 설치는 다음을 참고하세요.

https://taekho.tistory.com/18

 

C++ : mariaDB C/C++ Connector 설치하기

1. C/C++에서 mariaDB Server 데이터베이스을 사용하려면 mariaDB Connector를 설치해야한다. 2. mariaDB Connector 사이트에 접속한다.https://mariadb.com/downloads/connectors/ Download MariaDB Products & Tools | MariaDBDownload MariaD

taekho.tistory.com

 

 

 

 

2. MFC 프로젝트를 생성한다.(MFC앱 템플릿)

 

2.1 MFC 애플리케이션의 [애플리케이션 종류]를 아래 그림과 같이 설정한다.

 

 

2.2 MFC 애플리케이션의 [생성된 클래스]를 아래 그림과 같이 설정한다.

 

 

3. framework.h 파일에 #include <afxdb.h>를 추가한다.

 

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

 

4.1 MemberDTO.h파일을 추가한다.

#pragma once
#include <string>

class MemberDTO
{
public:
    int id;
    std::string forename;
	std::string surname;
	std::string email;
	MemberDTO() : id(0) {}
};

 

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

 

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

#pragma once

#include <vector>
#include <memory>
#include "MemberDTO.h"
#include <mariadb/conncpp.hpp>

class MemberDAO
{
private:
    sql::Driver* driver;

    std::string host;
    std::string database;
    std::string user;
    std::string password;

public:
    MemberDAO();

    std::unique_ptr<sql::Connection> getConnection();

    int insert(MemberDTO& dto);

    bool update(MemberDTO& dto);

    bool remove(int id);

    std::vector<MemberDTO> selectAll();
};

 

5.2 MemberDAO.cpp파일을 추가한다.

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

#include <iostream>

MemberDAO::MemberDAO()
{
    driver = sql::mariadb::get_driver_instance();

    host = "jdbc:mariadb://localhost:3306";
    database = "database1";

    user = "user1";
    password = "password1";
}

std::unique_ptr<sql::Connection> MemberDAO::getConnection()
{
    std::unique_ptr<sql::Connection> conn{driver->connect(host, user, password)};

    conn->setSchema(database);

    return conn;
}

int MemberDAO::insert(MemberDTO& dto)
{
    try
    {
        auto conn = getConnection();

        std::unique_ptr<sql::PreparedStatement> pstmt{
            conn->prepareStatement("INSERT INTO member (forename, surname, email) VALUES (?, ?, ?)") };

        pstmt->setString(1, dto.forename);
        pstmt->setString(2, dto.surname);
        pstmt->setString(3, dto.email);

        pstmt->executeUpdate();

        auto stmt =
            std::unique_ptr<sql::Statement>{
                conn->createStatement() };

        auto res =
            std::unique_ptr<sql::ResultSet>{
                stmt->executeQuery(
                    "SELECT LAST_INSERT_ID()") };

        if (res->next())
        {
            return res->getInt(1);
        }

        return 0;
    }
    catch (sql::SQLException& e)
    {
        std::cout << e.what() << std::endl;
        return -1;
    }
}

bool MemberDAO::update(MemberDTO& dto)
{
    try
    {
        auto conn = getConnection();

        std::unique_ptr<sql::PreparedStatement> pstmt{
            conn->prepareStatement(
                "UPDATE member SET "
                "forename=?, "
                "surname=?, "
                "email=?, "
                "WHERE id=?") };

        pstmt->setString(1, dto.forename);
        pstmt->setString(2, dto.surname);
        pstmt->setString(3, dto.email);
        pstmt->setInt(4, dto.id);

        pstmt->executeUpdate();

        return true;
    }
    catch (sql::SQLException& e)
    {
        std::cout << e.what() << std::endl;
        return false;
    }
}

bool MemberDAO::remove(int id)
{
    try
    {
        auto conn = getConnection();

        std::unique_ptr<sql::PreparedStatement> pstmt{
            conn->prepareStatement("DELETE FROM member WHERE id=?") };

        pstmt->setInt(1, id);

        pstmt->executeUpdate();

        return true;
    }
    catch (sql::SQLException& e)
    {
        std::cout << e.what() << std::endl;
        return false;
    }
}

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

    try
    {
        auto conn = getConnection();

        std::unique_ptr<sql::Statement> stmt{ conn->createStatement() };

        std::unique_ptr<sql::ResultSet> res{ stmt->executeQuery("SELECT * FROM member") };

        while (res->next())
        {
            MemberDTO dto;

            dto.id = res->getInt("id");
            dto.forename = res->getString("forename");
            dto.surname = res->getString("surname");
            dto.email = res->getString("email");

            list.push_back(dto);
        }
    }
    catch (sql::SQLException& e)
    {
        std::cout << e.what() << std::endl;
    }

    return list;
}

 

6. mariaDB 데이타를 보일 CListCtrl멤버변수와 실제 데이터를 가져오는 LoadMembers()함수를 MainView 클래스에 추가한다.

class CMainView : public CWnd
{
// ...
private:
	CListCtrl m_listCtrl;
	void LoadMembers();
};

 

6.1 CListCtrl의 리소스 ID를 등록한다.

      - 리소스뷰로 이동

      - xxx.rx 파일 선택후 우클릭

      - [리소스기호]를 선택하면 아래의 다이로그가 보인다.

      - 새로 만들기로 IDC_MEMBERLIST를 추가한다.

      - 주의 : 반드시 저장한다.

 

7. CListCtrl멤버변수에 Create하기 위해서 WM_CREATE와 WM_SIZE를 추가한다.

    - 프로젝트를 선택 후 [클래스 마법사] 선택한다.

    - 아래와 같이 보이면 된다.

 

7.1 아래와 같이 코드를 확인할 수 있다.

class CMainView : public CWnd
{
// ...
public:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnSize(UINT nType, int cx, int cy);
private:
	CListCtrl m_listCtrl;
	void LoadMembers();
};

 

8. CMainView::OnCreate(LPCREATESTRUCT lpCreateStruct)함수에 아래와 같이 추가한다.

 

int CMainView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  여기에 특수화된 작성 코드를 추가합니다.
	m_listCtrl.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT, CRect(0, 0, 0, 0), this, IDC_MEMBERLIST);

	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();

	return 0;
}

 

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

 

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

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

	m_listCtrl.DeleteAllItems();

	int i = 0;
	for (auto& m : members)
	{
		CString id;
		id.Format(_T("%d"), m.id);

		m_listCtrl.InsertItem(i, id);
		std::wstring wforename = UtfConverter::UTF8ToWString(m.forename);
		m_listCtrl.SetItemText(i, 1, CString(wforename.c_str()));
		std::wstring wsurname = UtfConverter::UTF8ToWString(m.surname);
		m_listCtrl.SetItemText(i, 2, CString(wsurname.c_str()));
		std::wstring wemail = UtfConverter::UTF8ToWString(m.email);
		m_listCtrl.SetItemText(i, 3, CString(wemail.c_str()));
		std::wstring wpassword = UtfConverter::UTF8ToWString(m.password);

		i++;
	}

 

10. CMainView::OnSize(UINT nType, int cx, int cy)함수에 아래와 같이 추가한다.

void CMainView::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	// TODO: 여기에 메시지 처리기 코드를 추가합니다.
	if(::IsWindow(m_listCtrl.GetSafeHwnd()))
	{
		m_listCtrl.MoveWindow(0, 0, cx, cy);
	}
}

 

11. mariaDB Server를 실행한다.

 

12. 앱을 실행 정상 동작하는지 확인한다.

 

13. 테이블의 데이터에 한글이 있으면 한글이 깨지는 문제가 발생한다.(해결책은 다음 절차를 추가한다.)

 

14. UtfConverter.h 파일을 추가한다.

#pragma once
#include <string>
#include <windows.h>

class UtfConverter
{
public:
    static std::wstring UTF8ToWString(const std::string& str)
    {
		return CA2W(str.c_str(), CP_UTF8);
    }

    static std::string WStringToUTF8(const std::wstring& wstr)
    {
        return CW2A(wstr.c_str(), CP_UTF8);
    }
};

 

15. CMainView::LoadMembers()함수를 아래와 같이 수정한다.

 

16. 실행하면 한글 데이터가 제대로 보임을 확인할 수 있다.

 

* 참고

 

1. 데이터 insert시에는 아래와 같이 착성하면된다.

    - CButton를 추가한다.

    - 클릭 이벤트에 아래와 같이 추가한다.

void CMainView::OnBnClickedAdd()
{
	MemberDAO dao;

	MemberDTO dto;

	CString text;
	m_editForeName.GetWindowText(text);
	dto.forename = UtfConverter::WStringToUTF8(std::wstring(text));
	
	m_editSurName.GetWindowText(text);
	dto.surname = UtfConverter::WStringToUTF8(std::wstring(text));
	
	m_editEmail.GetWindowText(text);
	dto.email = UtfConverter::WStringToUTF8(std::wstring(text));

	dao.insert(dto);


	LoadMembers();
}