다루는 내용
MFC 동적 연결 라이브러리 프로젝트 생성
외부에서 사용 가능한 클래스 만들기
ODBC 데이터 원본을 사용하여 MSSQL 사용하기
select * 쿼리 사용하기
insert 쿼리 사용하기
delete 쿼리 사용하기
update 쿼리 사용하기
select max(pid) 사용하기
1. MFC 동적 연결 라이브러리 프로젝트 생성
Visual Studio에서 MFC 동적 연결 라이브러리를 선택하여 프로젝트를 생성합니다.
프로젝트 이름은 ProductDB라고 할게요.
2. 외부에서 사용 가능한 클래스 만들기
여기에서는 네 가지 형식을 정의할 것입니다.
상품은 Product 클래스로 정의할 것입니다.
외부에서 상품 테이블에 접근하기 위한 기능은 ProductManager 클래스로 정의할 것입니다.
상품 ID를 키로 하고 상품 개체를 값으로 하는 map을 ProductMap 형식으로 타입 정의할 것입니다.
ProductMap형식 스코프의 iterater를 PIter 형식으로 타입 정의할 것입니다.
먼저 프로젝트에 Product 클래스를 추가하세요.
Product.h
DLL_CLASS 매크로 상수는 dll을 제공하는 곳과 사용하는 곳에 맞게 정의한 매크로입니다.
특별한 내용이 없으니 설명은 생략할게요.
#pragma once
#ifdef DIEMCUEYCH48957CJEY
#define DLL_CLASS __declspec(dllexport)
#else
#define DLL_CLASS __declspec(dllimport)
#endif
class DLL_CLASS Product
{
int pid;
CString pname;
int price;
CString desc;
public:
Product(int pid, CString pname, int price, CString desc);
CString GetPIDStr();
CString GetPriceStr();
CString GetPname();
CString GetDesc();
};
Product.cpp
소스 코드에서도 특별히 설명할 내용은 없습니다.
주의할 점은 DLL_CLASS 매크로 상수를 적절하게 정의하기 위한 매크로 상수명 정의를 pch.h 포함문보다는 밑에 product.h 포함문 보다는 위에 정의하세요.
#include "pch.h"
#define DIEMCUEYCH48957CJEY
#include "Product.h"
Product::Product(int pid, CString pname, int price, CString desc)
{
this->pid = pid;
this->pname = pname;
this->price = price;
this->desc = desc;
}
CString Product::GetPIDStr()
{
wchar_t buf[256];
wsprintf(buf, TEXT("%d"), pid);
return buf;
}
CString Product::GetPriceStr()
{
wchar_t buf[256];
wsprintf(buf, TEXT("%d"), price);
return buf;
}
CString Product::GetPname()
{
return pname;
}
CString Product::GetDesc()
{
return desc;
}
ProductManager.h
map과 Product.h를 포함합니다.
int(상품 ID)와 상품 개체를 키와 값으로하는 map을 ProductMap이라 정의할게요.
ProductMap 스코프의 iterator를 PIter라 정의할게요.
ProductManager 클래스에는 연결 문자열을 멤버 속성으로 갖습니다.
연결 문자열을 설정하는 SetConnStr 메서드를 제공합니다.
전체 상품을 조회하는 SelectAll 메서르를 제공합니다. 입력인자로 조회한 상품을 보관할 ProductMap 참조를 받습니다.
상품을 추가하는 AddProduct 메서를 제공합니다. 추가한 상품 ID를 반환합니다.
상품을 제거하는 RemoveProduct메서드와 수정하는 UpdateProduct 메서드를 제공합니다.
#pragma once
#include <map>
#include "Product.h"
using std::map;
typedef map<int, Product*> ProductMap;
typedef ProductMap::iterator PIter;
class DLL_CLASS ProductManager
{
CString constr;
public:
void SetConnStr(CString constr);
void SelectAll(ProductMap &pm);
int AddProduct(CString pname, int price, CString desc);
void RemoveProduct(int pid);
void UpdateProduct(int pid, CString pname, int price, CString desc);
};
ProductManager.cpp
다음은 ProductManager.cpp 소스 코드 내용입니다.
#include "pch.h"
#define DIEMCUEYCH48957CJEY
#include "ProductManager.h"
void ProductManager::SetConnStr(CString constr)
{
this->constr = constr;
}
void ProductManager::SelectAll(ProductMap& pm)
{
CDatabase db;
bool re = db.OpenEx(constr);
if (re == FALSE)
{
return;
}
CRecordset rs(&db);
CString s_pid;
int pid;
CString pname;
CString s_price;
int price;
CString desc;
rs.Open(CRecordset::forwardOnly, TEXT("select *from product"));
while (!rs.IsEOF())
{
rs.GetFieldValue((short)0, s_pid);
pid = _wtoi(s_pid);
rs.GetFieldValue((short)1, pname);
rs.GetFieldValue((short)2, s_price);
price = _wtoi(s_price);
rs.GetFieldValue((short)3, desc);
pm[pid] = new Product(pid, pname, price, desc);
rs.MoveNext();
}
}
int ProductManager::AddProduct(CString pname, int price, CString desc)
{
CDatabase db;
bool re = db.OpenEx(constr);
wchar_t query_str[200] = TEXT("");
wsprintf(query_str, TEXT("insert into product(pname,price,description) values('%s',%d,'%s');"),
pname, price, desc);
db.ExecuteSQL(query_str);
CRecordset rs(&db);
rs.Open(AFX_DB_USE_DEFAULT_TYPE,
TEXT("select MAX(pid) from product"));
CString pid;
if (!rs.IsEOF())
{
rs.GetFieldValue((short)0, pid);
}
rs.Close();
return _wtoi(pid);
}
void ProductManager::RemoveProduct(int pid)
{
CDatabase db;
bool re = db.OpenEx(constr);
wchar_t query_str[200] = TEXT("");
wsprintf(query_str, TEXT("delete from product where pid='%d'"), pid);
db.ExecuteSQL(query_str);
}
void ProductManager::UpdateProduct(int pid, CString pname, int price, CString desc)
{
CDatabase db;
bool re = db.OpenEx(constr);
wchar_t query_str[200] = TEXT("");
wsprintf(query_str, TEXT("update product set pname='%s',price=%d,description='%s' where pid='%d'"),
pname, price, desc, pid);
db.ExecuteSQL(query_str);
}
SetConnStr 메서드
ODBC 원본 데이터에 연결하기 위한 문자열을 입력 인자로 받아 설정합니다.
여기에서는 단순히 입력 인자로 받아 멤버 필드에 설정하는 단순한 작업을 수행합니다.
void ProductManager::SetConnStr(CString constr)
{
this->constr = constr;
}
SelectAll 메서드
select 구문을 수행한 결과를 순차적으로 접근하여 모든 결과를 확인합니다.
확인한 결과는 입력 인자로 전달받은 ProdcutMap 참조 개체에 보관합니다.
void ProductManager::SelectAll(ProductMap& pm)
{
CDatabase db;
bool re = db.OpenEx(constr);
if (re == FALSE)
{
return;
}
CRecordset rs(&db);
CString s_pid;
int pid;
CString pname;
CString s_price;
int price;
CString desc;
rs.Open(CRecordset::forwardOnly, TEXT("select *from product"));
while (!rs.IsEOF())
{
rs.GetFieldValue((short)0, s_pid);
pid = _wtoi(s_pid);
rs.GetFieldValue((short)1, pname);
rs.GetFieldValue((short)2, s_price);
price = _wtoi(s_price);
rs.GetFieldValue((short)3, desc);
pm[pid] = new Product(pid, pname, price, desc);
rs.MoveNext();
}
}
AddProduct 메서드
먼저 insert 쿼리를 통해 상품을 추가합니다.
그리고 select max(pid) from product 쿼리를 통해 추가한 상품의 pid를 반환합니다.
int ProductManager::AddProduct(CString pname, int price, CString desc)
{
CDatabase db;
bool re = db.OpenEx(constr);
wchar_t query_str[200] = TEXT("");
wsprintf(query_str, TEXT("insert into product(pname,price,description) values('%s',%d,'%s');"),
pname, price, desc);
db.ExecuteSQL(query_str);
CRecordset rs(&db);
rs.Open(AFX_DB_USE_DEFAULT_TYPE,
TEXT("select MAX(pid) from product"));
CString pid;
if (!rs.IsEOF())
{
rs.GetFieldValue((short)0, pid);
}
rs.Close();
return _wtoi(pid);
}
RemoveProduct 메서드
상품을 삭제하는 delete 쿼리를 실행합니다.
void ProductManager::RemoveProduct(int pid)
{
CDatabase db;
bool re = db.OpenEx(constr);
wchar_t query_str[200] = TEXT("");
wsprintf(query_str, TEXT("delete from product where pid='%d'"), pid);
db.ExecuteSQL(query_str);
}
UpdateProduct 메서드
상품을 수정하는 update 쿼리를 실행합니다.
void ProductManager::UpdateProduct(int pid, CString pname, int price, CString desc)
{
CDatabase db;
bool re = db.OpenEx(constr);
wchar_t query_str[200] = TEXT("");
wsprintf(query_str, TEXT("update product set pname='%s',price=%d,description='%s' where pid='%d'"),
pname, price, desc, pid);
db.ExecuteSQL(query_str);
}