TN053: DAO 데이터베이스 클래스에 대한 사용자 지정 DFX 루틴

참고 항목

DAO는 Access 데이터베이스와 함께 사용되며 Office 2013을 통해 지원됩니다. DAO 3.6은 최종 버전이며 사용되지 않는 것으로 간주합니다. Visual C++ 환경 및 마법사는 DAO를 지원하지 않습니다(DAO 클래스가 포함되어 있고 계속 사용할 수 있지만). 새 프로젝트에는 OLE DB 템플릿 또는 ODBC 및 MFC를 사용하는 것이 좋습니다. 기존 애플리케이션에 기본 DAO만 사용해야 합니다.

이 기술 참고에서는 DAO DFX(레코드 필드 교환) 메커니즘에 대해 설명합니다. DFX 루틴에서 발생하는 작업을 이해하기 위해 함수를 DFX_Text 예제로 자세히 설명합니다. 이 기술 노트에 대한 추가 정보 원본으로, 다른 개별 DFX 함수에 대한 코드를 검사할 수 있습니다. 사용자 지정 RFX 루틴(ODBC 데이터베이스 클래스와 함께 사용됨)이 필요할 수 있는 만큼 자주 사용자 지정 DFX 루틴이 필요하지 않을 수 있습니다.

이 기술 참고 사항에는 다음이 포함됩니다.

DFX 개요

DAO DFX(레코드 필드 교환 메커니즘)는 클래스를 사용할 CDaoRecordset 때 데이터를 검색하고 업데이트하는 절차를 간소화하는 데 사용됩니다. 이 프로세스는 클래스의 데이터 멤버를 사용하여 간소화됩니다 CDaoRecordset . 파생하면 CDaoRecordset테이블 또는 쿼리의 각 필드를 나타내는 파생 클래스에 데이터 멤버를 추가할 수 있습니다. 이 "정적 바인딩" 메커니즘은 간단하지만 모든 애플리케이션에 대해 선택한 데이터 페치/업데이트 방법이 아닐 수 있습니다. DFX는 현재 레코드가 변경될 때마다 모든 바인딩된 필드를 검색합니다. 통화가 변경될 때 모든 필드를 가져올 필요가 없는 성능에 민감한 애플리케이션을 개발하는 경우 "동적 바인딩"을 통해 CDaoRecordset::GetFieldValueCDaoRecordset::SetFieldValue 선택한 데이터 액세스 방법이 될 수 있습니다.

참고 항목

DFX 및 동적 바인딩은 상호 배타적이지 않으므로 정적 및 동적 바인딩의 하이브리드 사용을 사용할 수 있습니다.

예제 1 - DAO 레코드 필드 교환만 사용

(가정 - 파생 클래스 CMySet 가 이미 열려 있는 경우 CDaoRecordset )

// Add a new record to the customers table
myset.AddNew();

myset.m_strCustID = _T("MSFT");

myset.m_strCustName = _T("Microsoft");

myset.Update();

예제 2 - 동적 바인딩만 사용

(클래스rs를 사용 CDaoRecordset 하며 이미 열려 있다고 가정)

// Add a new record to the customers table
COleVariant  varFieldValue1 (_T("MSFT"),
    VT_BSTRT);

//Note: VT_BSTRT flags string type as ANSI,
    instead of UNICODE default
COleVariant  varFieldValue2  (_T("Microsoft"),
    VT_BSTRT);

rs.AddNew();

rs.SetFieldValue(_T("Customer_ID"),
    varFieldValue1);

rs.SetFieldValue(_T("Customer_Name"),
    varFieldValue2);

rs.Update();

예제 3 - DAO 레코드 필드 교환 및 동적 바인딩 사용

(-derived 클래스emp를 사용하여 직원 데이터를 CDaoRecordset검색하는 것으로 가정)

// Get the employee's data so that it can be displayed
emp.MoveNext();

// If user wants to see employee's photograph,
// fetch it
COleVariant varPhoto;
if (bSeePicture)
    emp.GetFieldValue(_T("photo"),
    varPhoto);

// Display the data
PopUpEmployeeData(emp.m_strFirstName,
    emp.m_strLastName,
    varPhoto);

DFX 작동 방식

DFX 메커니즘은 MFC ODBC 클래스에서 사용하는 RFX(레코드 필드 교환) 메커니즘과 비슷한 방식으로 작동합니다. DFX와 RFX의 원칙은 동일하지만 내부적으로는 여러 가지 차이점이 있습니다. DFX 함수의 디자인은 사실상 모든 코드가 개별 DFX 루틴에서 공유되도록 했습니다. 가장 높은 수준의 DFX는 몇 가지 작업만 수행합니다.

  • 필요한 경우 DFX는 SQL SELECT 절 및 SQL PARAMETERS 절을 생성합니다.

  • DFX는 DAO 함수 GetRows 에서 사용하는 바인딩 구조를 생성합니다(나중에 자세히 설명).

  • DFX는 더티 필드를 검색하는 데 사용되는 데이터 버퍼를 관리합니다(이중 버퍼링이 사용되는 경우).

  • DFX는 NULLDIRTY 상태 배열을 관리하고 업데이트에 필요한 경우 값을 설정합니다.

DFX 메커니즘의 핵심은 CDaoRecordset 파생 클래스의 함수입니다 DoFieldExchange . 이 함수는 적절한 작업 유형의 개별 DFX 함수에 대한 호출을 디스패치합니다. 내부 MFC 함수를 호출 DoFieldExchange 하기 전에 작업 유형을 설정합니다. 다음 목록에서는 다양한 작업 유형과 간략한 설명을 보여 있습니다.

연산 설명
AddToParameterList PARAMETERS 절을 빌드합니다.
AddToSelectList BUILDS SELECT 절
BindField 바인딩 구조 설정
BindParam 매개 변수 값 설정
Fixup NULL 상태 설정
AllocCache 더티 검사 캐시 할당
StoreField 현재 레코드를 캐시에 저장합니다.
LoadField 멤버 값으로 캐시 복원
FreeCache 캐시 해제
SetFieldNull 필드 상태 및 값을 NULL로 설정
MarkForAddNew PSEUDO NULL이 아닌 경우 필드 더티 표시
MarkForEdit 캐시와 일치하지 않는 경우 필드 더티 표시
SetDirtyField 더티 표시된 필드 값을 설정합니다.

다음 섹션에서는 각 작업에 대해 DFX_Text자세히 설명합니다.

DAO 레코드 필드 교환 프로세스에 대해 이해하는 가장 중요한 기능은 개체의 CDaoRecordset 함수를 GetRows 사용한다는 것입니다. DAO GetRows 함수는 여러 가지 방법으로 작동할 수 있습니다. 이 기술 노트는 이 기술 노트의 범위를 벗어나는 경우에만 간략하게 설명 GetRows 합니다. DAO GetRows 는 여러 가지 방법으로 작동할 수 있습니다.

  • 한 번에 여러 레코드와 여러 데이터 필드를 가져올 수 있습니다. 이렇게 하면 큰 데이터 구조를 처리하는 복잡성과 각 필드 및 구조의 각 데이터 레코드에 대한 적절한 오프셋을 처리하는 복잡성으로 데이터 액세스 속도가 빨라집니다. MFC는 이 여러 레코드 페치 메커니즘을 활용하지 않습니다.

  • 또 다른 방법은 GetRows 프로그래머가 하나의 데이터 레코드에 대해 각 필드의 검색된 데이터에 대한 바인딩 주소를 지정할 수 있도록 하는 것입니다.

  • 또한 DAO는 호출자가 메모리를 할당할 수 있도록 가변 길이 열에 대해 호출자에 "콜백"합니다. 이 두 번째 기능은 데이터 복사본 수를 최소화하고 데이터를 클래스의 멤버( CDaoRecordset 파생 클래스)로 직접 저장하도록 허용하는 이점이 있습니다. 이 두 번째 메커니즘은 MFC가 파생 클래스의 데이터 멤버에 CDaoRecordset 바인딩하는 데 사용하는 방법입니다.

사용자 지정 DFX 루틴의 기능

이 논의에서 DFX 함수에서 구현되는 가장 중요한 작업은 성공적으로 호출 GetRows하는 데 필요한 데이터 구조를 설정하는 기능이어야 합니다. DFX 함수도 지원해야 하지만 호출을 올바르게 준비하는 GetRows 것만큼 중요하거나 복잡한 작업은 없습니다.

DFX의 사용은 온라인 설명서에 설명되어 있습니다. 기본적으로 두 가지 요구 사항이 있습니다. 먼저 각 바인딩된 필드 및 매개 변수에 CDaoRecordset 대한 파생 클래스에 멤버를 추가해야 합니다. 다음을 CDaoRecordset::DoFieldExchange 재정의해야 합니다. 멤버의 데이터 형식이 중요합니다. 데이터베이스에 있는 필드의 데이터와 일치하거나 적어도 해당 형식으로 변환할 수 있어야 합니다. 예를 들어 긴 정수와 같은 데이터베이스의 숫자 필드는 항상 텍스트로 변환되어 멤버에 CString 바인딩될 수 있지만 데이터베이스의 텍스트 필드는 반드시 긴 정수와 같은 숫자 표현으로 변환되지 않고 긴 정수 멤버에 바인딩될 수도 있습니다. DAO 및 Microsoft Jet 데이터베이스 엔진은 MFC가 아닌 변환을 담당합니다.

DFX_Text 세부 정보

앞에서 멘션 DFX 작동 방식을 설명하는 가장 좋은 방법은 예제를 통해 작업하는 것입니다. 이 목적을 위해 내부를 통해 가는 것은 DFX의 DFX_Text 적어도 기본적인 이해를 제공하는 데 도움이 아주 잘 작동해야합니다.

  • AddToParameterList

    이 작업은 Jet에 필요한 SQL PARAMETERS 절("Parameters <param name>, <param type> ... ;")을 빌드합니다. 각 매개 변수는 RFX 호출에 지정된 대로 명명되고 입력됩니다. 개별 형식의 이름을 보려면 함수 함수 CDaoFieldExchange::AppendParamType 를 참조하세요. 의 경우 DFX_Text사용되는 형식은 텍스트입니다.

  • AddToSelectList

    SQL SELECT 절을 빌드합니다. DFX 호출에 지정된 열 이름이 단순히 추가되기 때문에 이는 매우 간단합니다("SELECT <column name>, ...").

  • BindField

    가장 복잡한 작업입니다. 앞에서 멘션 사용하던 DAO 바인딩 구조 GetRows 가 설정되는 위치입니다. 코드에서 DFX_Text 볼 수 있듯이 구조체의 정보 유형에는 사용된 DAO 형식(DAO_CHAR 또는 DAO_WCHARDFX_Text)이 포함됩니다. 또한 사용되는 바인딩 유형도 설정됩니다. 이전 섹션에서 GetRows 는 간단히 설명했지만 MFC에서 사용하는 바인딩 유형이 항상 직접 주소 바인딩(DAOBINDING_DIRECT)임을 설명하기에 충분했습니다. 또한 MFC가 메모리 할당을 제어하고 올바른 길이의 주소를 지정할 수 있도록 콜백 바인딩과 같은 DFX_Text가변 길이 열 바인딩도 사용됩니다. 즉, MFC는 항상 DAO에 데이터를 배치할 "위치"를 알려 멤버 변수에 직접 바인딩할 수 있습니다. 나머지 바인딩 구조는 메모리 할당 콜백 함수의 주소 및 열 바인딩 형식(열 이름별 바인딩)과 같은 항목으로 채워집니다.

  • BindParam

    매개 변수 멤버에 지정된 매개 변수 값을 사용하여 호출 SetParamValue 하는 간단한 작업입니다.

  • Fixup

    각 필드에 대한 NULL 상태 채웁니다.

  • SetFieldNull

    이 작업은 각 필드 상태 NULL표시하고 멤버 변수의 값을 PSEUDO_NULL 설정합니다.

  • SetDirtyField

    더티 표시된 각 필드에 대한 호출 SetFieldValue 입니다.

모든 다시 기본 작업은 데이터 캐시 사용만 처리합니다. 데이터 캐시는 특정 항목을 더 간단하게 만드는 데 사용되는 현재 레코드에 있는 데이터의 추가 버퍼입니다. 예를 들어 "더티" 필드를 자동으로 검색할 수 있습니다. 온라인 설명서에 설명된 대로 완전히 또는 필드 수준에서 해제할 수 있습니다. 버퍼의 구현은 맵을 활용합니다. 이 맵은 동적으로 할당된 데이터 복사본을 "바인딩된" 필드(또는 CDaoRecordset 파생 데이터 멤버)의 주소와 일치시킬 때 사용됩니다.

  • AllocCache

    캐시된 필드 값을 동적으로 할당하고 맵에 추가합니다.

  • FreeCache

    캐시된 필드 값을 삭제하고 맵에서 제거합니다.

  • StoreField

    현재 필드 값을 데이터 캐시에 복사합니다.

  • LoadField

    캐시된 값을 필드 멤버에 복사합니다.

  • MarkForAddNew

    현재 필드 값이 NULL이 아닌지 확인하고 필요한 경우 더티 표시합니다.

  • MarkForEdit

    현재 필드 값을 데이터 캐시와 비교하고 필요한 경우 더티 표시합니다.

표준 데이터 형식에 대한 기존 DFX 루틴에서 사용자 지정 DFX 루틴을 모델링합니다.

참고 항목

번호별 기술 참고 사항
범주별 기술 참고 사항