반응형

MFC에서 SQLite3에 한글 문자열을 저장하고 다시 불러오는 간단한 예제를 만들어보았습니다.

이쪽 분야를 전문적으로 작성하지 않기 때문에 좀 이상하게 작성된게 있을 수도 있습니다^^;





MFC에서 사용할 SQLIte를 다운로드 받아야 합니다. 

 

https://www.sqlite.org/download.html 에서  SQLite 소스 코드와 DLL 파일을 다운로드 합니다.

생성한 프로젝트에 따라 x86 또는 x64 DLL을 사용합니다. 본 포스트에서는 x64를 사용합니다. 




압축을 풀어서 C:\SQLite3에 복사해줍니다. 




개발자 명령 프롬프트 또는 Developer Command Prompt를 검색하여 실행합니다.

Visual Studio 2019에서도 동일하게 진행할 수 있습니다.




다음 명령을 사용하여 lib 파일을 생성합니다.

32비트인 경우에는 x64대신 x86을 사용하면 됩니다.

 

lib /def:sqlite3.def /machine:x64

 




새로운 MFC 프로젝트를  생성합니다. 




응용 프로그램 종류로 대화 상자 기반을 선택하고, SDL은 체크해제 한 후, 마침 버튼을 클릭합니다.




솔루션 플랫폼을 x64로 변경합니다.



메뉴에서 프로젝트 > 속성을 선택하고  구성을 모든 구성으로 변경합니다.



왼쪽 메뉴에서 C/C++를 선택한 후, 추가 포함 디렉토리 항목에 C:\SQlite3을 입력합니다. 




왼쪽 메뉴에서 링커를 선택하고 추가 라이브러리 디렉터리 항목에 C:\SQLite3을 입력합니다.




왼쪽 메뉴에서 디버깅을 선택한 후, 환경 항목에 다음을 입력합니다. 

 

PATH=C:\SQLite3;%PATH%

 




프로젝트 창에서 리소스 뷰를 선택합니다. 




 Dialog 항목에 있는 IDD_ABOUTBOX 아래에 있는 다이얼로그를 선택합니다. 

리소스 뷰가 보이지 않는 경우 메뉴에서 보기 > 리소스 뷰를 선택하세요. 




다음처럼 UI를 구성하고 변수를 추가해줍니다. 




리스트 컨트롤의 속성에서 Single Selection을 True로 변경합니다.

 

View를 Report로 변경합니다.



파일 이름에 Dlg가 포함된 cpp 파일에 코드를 추가할 차례입니다. 

제 경우에는 SQLite3_ExampleDlg.cpp 입니다. 



필요한 헤더파일과 함수 그리고 SQLite 라이브러리를 로드하기 위한  코드를 추가합니다.

#include "sqlite3.h"
#include <assert.h>

#pragma comment(lib, "sqlite3.lib")





// SQLite는 UTF8을 사용하기 때문에 코드 변환이 필요합니다.
// 출처 - http://dolphin.ivyro.net/file/algorithm/SQLite/tutoria03.html
int AnsiToUTF8(char* szSrc, char* strDest, int destSize)
{
	WCHAR 	szUnicode[255];
	char 	szUTF8code[255];

	int nUnicodeSize = MultiByteToWideChar(CP_ACP, 0, szSrc, (int)strlen(szSrc), szUnicode, sizeof(szUnicode));
	int nUTF8codeSize = WideCharToMultiByte(CP_UTF8, 0, szUnicode, nUnicodeSize, szUTF8code, sizeof(szUTF8code), NULL, NULL);
	assert(destSize > nUTF8codeSize);
	memcpy(strDest, szUTF8code, nUTF8codeSize);
	strDest[nUTF8codeSize] = 0;
	return nUTF8codeSize;
}

int UTF8ToAnsi(char* szSrc, char* strDest, int destSize)
{
	WCHAR 	szUnicode[255];
	char 	szAnsi[255];

	int nSize = MultiByteToWideChar(CP_UTF8, 0, szSrc, -1, 0, 0);
	int nUnicodeSize = MultiByteToWideChar(CP_UTF8, 0, szSrc, -1, szUnicode, nSize);
	int nAnsiSize = WideCharToMultiByte(CP_ACP, 0, szUnicode, nUnicodeSize, szAnsi, sizeof(szAnsi), NULL, NULL);
	assert(destSize > nAnsiSize);
	memcpy(strDest, szAnsi, nAnsiSize);
	strDest[nAnsiSize] = 0;
	return nAnsiSize;
}






초기에 필요한 데이터베이스 파일 생성, 테이블 생성을 합니다. 

그리고  데이터베이스로부터 데이터를 가져와 리스트 컨트롤에 보여줍니다.

BOOL CSQLite3ExampleDlg::OnInitDialog()
{
	. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

	// TODO: 여기에 추가 초기화 작업을 추가합니다.

	// 한줄 선택
	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

	// 리스트 컨트롤에 컬럼 이름 입력
	m_list.InsertColumn(0, L"이름");
	m_list.SetColumnWidth(0, 120);
	m_list.InsertColumn(1, L"전화번호");
	m_list.SetColumnWidth(1, 240);


	
	// 데이터베이스 파일 생성 및 열기
	sqlite3 *db;
	sqlite3_stmt *stmt;
	char *errmsg = NULL;

	int rc = sqlite3_open("test.db", &db);

	if (rc != SQLITE_OK)
	{
		printf("Failed to open DB\n");
		sqlite3_close(db);
		exit(1);
	}


	//SQL 테이블 생성
	char *sql;
	sql = "CREATE TABLE IF NOT EXISTS DB("
		"ID INTEGER PRIMARY        KEY     AUTOINCREMENT,"
		"NAME          TEXT     NOT NULL,"
		"TEL           TEXT     NOT NULL);";

	rc = sqlite3_exec(db, sql, NULL, NULL, &errmsg);

	if (rc != SQLITE_OK)
	{
		printf("create table");
		sqlite3_free(errmsg);
		sqlite3_close(db);
		exit(1);
	}

	


      // 테이블을 읽어와 리스트 컨트롤에 보여주기
	sqlite3_prepare_v2(db, "select * from db", -1, &stmt, NULL);

	while (sqlite3_step(stmt) != SQLITE_DONE) {
		int i;
		int num_cols = sqlite3_column_count(stmt);


		char szAnsi[300];
		UTF8ToAnsi((char *)sqlite3_column_text(stmt, 1), szAnsi, 300);
		CString name(szAnsi);

		UTF8ToAnsi((char *)sqlite3_column_text(stmt, 2), szAnsi, 300);
		CString tel(szAnsi);

		int nItem = m_list.InsertItem(0, name);
		m_list.SetItemText(nItem, 1, tel);

	}

	sqlite3_finalize(stmt);

	sqlite3_close(db);


	return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}






추가 버튼 클릭시 실행되는 코드입니다. 

void CSQLite3ExampleDlg::OnBnClickedAdd()
{

	// 에디터 박스에 입력된 데이터를 리스트컨트롤에 입력합니다. 
	CString name;
	m_name.GetWindowText(name);

	CString tel;
	m_tel.GetWindowText(tel);


	int nItem = m_list.InsertItem(0, name);
	m_list.SetItemText(nItem, 1, tel);


	m_name.SetWindowTextW(L"");
	m_tel.SetWindowTextW(L"");

	

	sqlite3 *db;
	int rc = sqlite3_open("test.db", &db);

	if (rc != SQLITE_OK)
	{
		printf("Failed to open DB\n");
		sqlite3_close(db);
		exit(1);
	}

	

	char * s_name;

	int sLen = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
	s_name = new char[sLen + 1];
	WideCharToMultiByte(CP_ACP, 0, name, -1, s_name, sLen, NULL, NULL);

	char szName[100];
	AnsiToUTF8(s_name, szName, 100);

	delete[]s_name;
	



	char * s_tel;

	sLen = WideCharToMultiByte(CP_ACP, 0, tel, -1, NULL, 0, NULL, NULL);
	s_tel = new char[sLen + 1];
	WideCharToMultiByte(CP_ACP, 0, tel, -1, s_tel, sLen, NULL, NULL);

	char szTel[100];
	AnsiToUTF8(s_tel, szTel, 100);

	delete[]s_tel;

	   

	char *errmsg = NULL;
	char sql[255] = { 0 };
	sprintf(sql, "insert into db(name, tel) values('%s','%s');", szName, szTel);

	if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, &errmsg))
	{
		printf("insert");
	}

	sqlite3_close(db);


}

 

 

삭제 버튼 클릭시 실행되는 코드입니다.

void CSQLite3ExampleDlg::OnBnClickedRemove()
{
	// 리스트 컨트롤에서 선택한 아이템을 제거합니다.
	int row = m_list.GetSelectionMark();
	CString name = m_list.GetItemText(row, 0);


	char * s_name;

	int sLen = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
	s_name = new char[sLen + 1];
	WideCharToMultiByte(CP_ACP, 0, name, -1, s_name, sLen, NULL, NULL);

	char szName[100];
	AnsiToUTF8(s_name, szName, 100);

	delete[]s_name;



	sqlite3 *db;
	int rc = sqlite3_open("test.db", &db);

	if (rc != SQLITE_OK)
	{
		printf("Failed to open DB\n");
		sqlite3_close(db);
		exit(1);
	}


	char *errmsg = NULL;
	char sql[255] = { 0 };
	sprintf(sql, "delete from db where name = '%s';", szName);

	if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, &errmsg))
	{
		printf("delete");
	}


	
	sqlite3_close(db);


	m_list.DeleteItem(row);


}

 

작성 2020. 3. 23

 

반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts