ADO.NET을 사용한 데이터 액세스 소개

ADO.NET을 사용하여 응용 프로그램을 개발하는 경우 데이터를 사용하는 데 필요한 요구 사항이 다릅니다. 단순히 폼에 데이터를 표시해야 할 경우가 있으며 다른 회사와 정보를 공유해야 할 경우도 있습니다.

ADO.NET에서 데이터를 사용하려면 알아야 할 기본 개념이 있습니다. 데이터를 포함한 XML 파일을 직접 편집하는 등의 데이터 처리에 대한 일부 자세한 내용은 알 필요가 없지만 ADO.NET의 데이터 아키텍처, 주요 데이터 구성 요소 및 결합 방식 등을 이해하면 매우 유용합니다.

여기에서는 이와 같이 가장 중요한 개념들을 심도있게 다룹니다. 이 항목에 언급된 것보다 훨씬 많은 데이터 집합이 있지만, ADO.NET의 데이터 통합에 대한 기본 개념을 소개하기 위해 기타 자세한 내용을 생략합니다.

참고   Visual Studio 데이터 액세스 구성 요소를 포함하는 응용 프로그램을 배포할 때에는 응용 프로그램을 설치하는 사용자가 MDAC(Microsoft Data Access Components) 버전 2.7 이상을 가지고 있는지 확인해야 합니다. 자세한 내용은 Microsoft Data Access Components의 시작 조건 추가를 참조하십시오.

ADO.NET에서는 연결을 계속 유지할 필요가 없습니다.

일반적인 클라이언트/서버 응용 프로그램에서는 구성 요소에서 데이터베이스에 연결을 설정하고 응용 프로그램이 실행되는 동안 열린 상태를 유지합니다. 그러나 다음과 같은 여러 가지 이유 때문에 이 방식을 사용하면 비실용적인 경우가 많습니다.

  • 데이터베이스 연결을 열린 상태로 유지하면 중요한 시스템 리소스를 차지하게 됩니다. 일반적으로 데이터베이스에서는 소수의 동시 연결만 유지할 수 있으며 여기서 발생하는 오버헤드는 전체 응용 프로그램 성능을 저하시킵니다.
  • 마찬가지로 열린 데이터베이스 연결이 필요한 응용 프로그램은 확장하기가 매우 어렵습니다. 확장하기 어려운 응용 프로그램은 사용자가 네 명인 경우에는 제대로 작동하더라도 사용자가 백 명이 되면 제대로 작동하지 않을 수도 있습니다. ASP.NET 웹 응용 프로그램은 특히 쉽게 확장할 수 있어야 합니다. 주문량이 늘어나면 매우 짧은 시간에도 웹 사이트의 소통량이 증가할 수 있기 때문입니다.
  • ASP.NET 웹 응용 프로그램에서 구성 요소는 본질적으로 서로 연결이 끊어져 있습니다. 브라우저는 서버로부터 페이지를 요청합니다. 서버가 페이지의 처리를 끝내고 전송한 후에는 다음 요청이 있을 때까지 브라우저와의 연결을 끊습니다. 이러한 상황에서 데이터의 소비자(클라이언트)가 데이터를 추가로 액세스할지 여부를 알 수 없기 때문에 데이터베이스에 열린 연결을 유지하는 것은 비생산적입니다.
  • 항상 연결된 데이터를 기반으로 하는 모델에서 연결된 아키텍처를 사용하여 응용 프로그램 및 기업 간에 데이터를 교환하는 것은 어렵고 비실용적입니다. 두 구성 요소가 같은 데이터를 공유해야 할 경우, 구성 요소가 서로 연결되어 있거나 구성 요소 간에 데이터를 주고 받을 수 있는 방식이 고안되어야 합니다.

이러한 이유 때문에 ADO.NET을 통한 데이터 액세스는 연결 사용을 최소화하는 아키텍처를 기반으로 디자인됩니다. 응용 프로그램은 데이터를 페치(fetch)하거나 업데이트하는 동안만 데이터베이스에 연결됩니다. 데이터베이스는 대부분 유휴 상태인 연결에 의해 제한되지 않으므로 다수의 사용자에게 서비스할 수 있습니다.

데이터베이스 상호 작용은 데이터 명령을 통해 수행됩니다.

데이터베이스에서 작업을 수행하려면 SQL 문을 포함한 저장 프로시저 또는 SQL 문을 실행합니다. SQL 문이나 저장 프로시저를 사용하여 행을 읽거나 쓰고 더하기나 평균 계산 같은 집계 기능을 수행합니다. 또한 SQL 문이나 저장 프로시저를 사용하여 테이블 또는 열을 만들고 수정하며 트랜잭션을 수행하는 등의 작업을 할 수 있습니다.

ADO.NET에서는 데이터 명령을 사용하여 SQL 문 또는 저장 프로시저를 패키지로 만듭니다. 예를 들어, 데이터베이스의 행 집합을 읽으려면 데이터 명령을 만들고 SQL Select 문의 텍스트를 사용하거나 레코드를 페치(fetch)하는 저장 프로시저의 이름을 사용하여 명령을 구성합니다.

행을 얻으려면 다음 작업을 수행합니다.

  1. 연결을 엽니다.
  2. 명령의 실행 메서드를 호출하여 실행 메서드에서 다음과 같은 작업을 수행합니다.
    1. 명령에서 참조하는 SQL 문 또는 저장 프로시저를 실행합니다.

    2. 그런 다음 연결을 닫습니다.

      연결은 SQL 문 또는 저장 프로시저를 실행하는 동안만 열려 있습니다.

명령의 실행 메서드를 호출하면 메서드에서 값이 반환됩니다. 데이터베이스를 업데이트하는 명령은 영향을 받은 행의 개수를 반환합니다. 다른 종류의 명령은 오류 코드를 반환합니다. 명령에서 SELECT 문을 통해 데이터베이스를 쿼리하면 행 집합을 반환할 수 있습니다. 매우 빠르고 앞으로만 이동할 수 있는 읽기 전용 커서의 역할을 하는 데이터 판독기를 사용하여 이러한 행을 페치(fetch)할 수 있습니다. 자세한 내용은 DataReader를 사용하여 데이터 검색을 참조하십시오.

보안 정보   CommandType 속성을 텍스트로 설정한 상태에서 데이터 명령을 사용하는 경우, 클라이언트에서 전송된 정보를 데이터베이스에 전달하기 전에 이 정보를 자세히 검사해야 합니다. 악의적인 사용자가 데이터베이스에 무단으로 액세스하거나 데이터베이스를 훼손하기 위해 수정된 SQL 문이나 추가적인 SQL 문을 전송(주입)할 수도 있습니다. 사용자 입력을 데이터베이스에 전송하기 전에 항상 정보의 유효성을 검사해야 합니다. 가능하면 항상 매개 변수 있는 쿼리나 저장 프로시저를 사용하는 것이 좋습니다. 자세한 내용은 스크립트 악용을 참조하십시오.

여러 행을 읽은 다음 업데이트하는 등과 같이 둘 이상의 작업을 수행해야 할 경우에는 각 작업에 대해 하나씩, 여러 개의 데이터 명령을 사용합니다. 각 작업은 개별적으로 수행됩니다. 예를 들어, 행을 읽으려면 연결을 열고 행을 읽은 다음 연결을 닫습니다. 데이터를 업데이트하려면 다시 연결을 열고 데이터를 업데이트한 다음 연결을 닫습니다.

데이터 명령에는 다음과 같이 매개 변수화된 쿼리를 만들 수 있는 매개 변수 또는 매개 변수 개체의 컬렉션이 포함될 수 있습니다.

Select * From customers Where (customer_id = @customerid)

그런 다음 런타임에 매개 변수를 설정하고 명령을 실행하여 원하는 데이터를 반환하거나 업데이트할 수 있습니다.

데이터 집합에 데이터를 캐싱할 수 있습니다.

가장 일반적인 데이터 작업은 데이터베이스에서 데이터를 검색하여 해당 데이터를 표시하고 처리하거나 다른 구성 요소로 보내는 것입니다. 대부분의 경우 응용 프로그램에서 하나의 레코드만 처리하는 것이 아니라 고객 목록, 금일 주문 등과 같은 레코드 집합을 처리해야 하며, 이러한 레코드 집합은 여러 테이블에 있습니다(예: 고객과 고객의 모든 주문, "Smith"라는 이름의 모든 저자와 그들이 저술한 책, 기타 유사한 관련 레코드 집합 등).

일반적으로 응용 프로그램에서 이러한 레코드는 페치(fetch)된 다음 그룹으로 처리됩니다. 예를 들어, "Smith"라는 이름의 저자를 모두 검색하고 그 중 한 사람의 책을 검토한 후에 다음 사람으로 이동할 수 있습니다.

많은 경우에 응용 프로그램에서 다음 레코드를 처리할 때마다 데이터베이스를 다시 검색하는 것은 실용적이지 않습니다. 그렇게 할 경우에는 열린 연결을 줄임으로써 얻어지는 이점이 상당 부분 훼손됩니다. 이러한 문제를 해결하려면 데이터베이스에서 검색된 레코드를 임시로 저장한 다음 이 임시 집합을 사용하면 됩니다.

다음은 데이터 집합에 대한 설명입니다. 데이터 집합은 데이터 소스에서 검색된 레코드의 캐시입니다. 데이터 집합은 가상 데이터 저장소처럼 동작합니다. 즉, 데이터 집합에는 실제 데이터베이스의 테이블을 기반으로 하는 하나 이상의 테이블이 포함되고, 이 테이블 간의 관계와 테이블에 포함시킬 수 있는 데이터의 제약 조건에 대한 정보가 포함됩니다.

데이터 집합의 데이터는 일반적인 데이터베이스에 있는 내용을 상당히 축약시킨 것입니다. 그러나 실제 데이터를 사용하는 것과 거의 동일한 방식으로 이 데이터를 사용할 수 있습니다. 또한 데이터를 사용하는 동안 데이터베이스에 연결되지 않은 상태를 유지하므로 데이터베이스에서 다른 작업을 수행할 수도 있습니다.

물론 데이터를 검색할 때처럼 자주는 아니더라도 종종 데이터베이스의 데이터를 업데이트해야 합니다. 데이터 집합에서 업데이트 작업을 수행하고 업데이트된 내용을 내부 데이터베이스에 쓸 수 있습니다.

중요한 점은 데이터 집합은 수동적인 데이터 컨테이너라는 사실입니다. 실제로 데이터베이스에서 데이터를 페치(fetch)하고 이를 다시 데이터베이스에 쓰려면(선택 사항) 데이터 어댑터를 사용합니다. 데이터 어댑터에는 데이터 집합의 단일 테이블을 채우고 데이터베이스의 해당 테이블을 업데이트하는 데 사용하는 하나 이상의 데이터 명령이 들어 있습니다. 데이터 어댑터에는 대개 데이터베이스의 행을 선택, 삽입, 업데이트 및 삭제하는 네 개의 명령이 들어 있습니다. 따라서 데이터 어댑터의 Fill 메서드는 호출될 때마다 SELECT au_id, au_lname, au_fname FROM authors와 같은 SQL 문을 실행합니다.

데이터 집합은 데이터베이스의 데이터를 별도로 복사한 것이기 때문에 데이터베이스의 현재 상태를 나타내지 않을 수도 있습니다. 가장 최근에 다른 사용자가 변경한 내용을 보려면 해당 Fill 메서드를 호출하여 데이터 집합을 새로 고치면 됩니다.

데이터 집합을 사용하면 필요한 경우 구성 요소가 데이터 집합을 교환할 수 있습니다. 예를 들어, 중간 계층의 비즈니스 개체가 데이터 집합을 만들고 채운 다음 응용 프로그램의 다른 구성 요소로 보내 처리하도록 할 수 있습니다. 즉, 구성 요소가 개별적으로 데이터베이스를 쿼리할 필요가 없습니다.

데이터 집합은 데이터 소스와 별개입니다.

데이터 집합은 데이터베이스에서 가져온 데이터의 캐시 역할을 하지만 실제로 데이터베이스와는 관계가 없습니다. 데이터 집합은 컨테이너이며, 데이터 어댑터에서 실행되는 저장 프로시저나 SQL 명령으로 채워집니다.

데이터 집합은 데이터 소스와 직접 결합되어 있지 않기 때문에 여러 소스의 데이터를 통합하기에 매우 적합한 지점입니다. 예를 들어, 데이터 집합의 일부 데이터는 사용자의 데이터베이스에서 가져오고 다른 부분은 기타 데이터베이스나 스프레드시트와 같은 비데이터베이스 소스에서 가져올 수 있습니다. 데이터 집합의 일부 데이터는 다른 구성 요소에서 보내는 스트림으로 전달될 수 있습니다. 데이터를 데이터 집합으로 가져오면 원래의 소스와 관계 없이 일관된 개체 모델을 사용하여 이 데이터를 처리할 수 있습니다.

데이터는 XML로 유지됩니다.

데이터를 데이터 저장소에서 데이터 집합으로 이동시킨 다음 여러 구성 요소로 다시 이동시킬 필요가 있습니다. ADO.NET에서는 데이터를 XML 형식으로 전송합니다. 마찬가지로 데이터가 파일 등으로 유지되어야 하는 경우에도 XML로 저장됩니다. XML 파일이 있으면 이를 다른 데이터 소스처럼 사용할 수 있고, 이 파일로부터 데이터 집합을 만들 수 있습니다.

ADO.NET에서 XML은 데이터의 기본 형식입니다. ADO.NET 데이터 API는 데이터 집합의 정보를 기반으로 XML 파일 또는 스트림을 자동으로 만든 다음 다른 구성 요소로 보냅니다. 둘째 구성 요소는 유사한 API를 호출하여 XML을 읽고 다시 데이터 집합에 저장할 수 있습니다. 데이터는 데이터 집합에 XML로 저장되지 않으므로 XML 파서를 사용하여 데이터 집합의 데이터를 구문 분석할 수 없지만, 대신 더욱 효율적인 형식으로 저장됩니다.

XML에 기반한 데이터 프로토콜을 사용하는 데에는 다음과 같은 여러 가지 장점이 있습니다.

  • XML은 업계 표준 형식입니다. 즉, 구성 요소와 XML이 호환되면 응용 프로그램의 데이터 구성 요소가 다른 응용 프로그램의 다른 구성 요소와 데이터를 교환할 수 있습니다. 여러 응용 프로그램은 XML과 호환되도록 작성되므로 서로 다른 응용 프로그램 간에 뛰어난 교환 기능을 제공합니다.
  • XML은 텍스트 기반입니다. XML 데이터 표현은 이진 정보를 사용하지 않으므로 HTTP와 같은 모든 프로토콜을 통해 보낼 수 있습니다. 대부분의 방화벽은 이진 정보를 차단하지만 XML로 작성된 정보는 구성 요소가 쉽게 교환할 수 있습니다.

일반적으로 XML에 대해 잘 알지 못해도 ADO.NET에서 데이터를 사용할 수 있습니다. 필요한 경우 ADO.NET에서 데이터를 XML로 또는 그 반대로 자동 변환하므로 일반적인 프로그래밍 방법을 사용하여 데이터와 상호 작용할 수 있습니다.

스키마가 데이터 구조를 정의합니다.

데이터베이스에서 읽고 쓰거나 데이터 집합을 사용하기 위해 XML에 대해 알 필요는 없지만 XML을 직접 사용해야 할 경우가 있습니다. 데이터에 액세스하는 대신 데이터의 디자인 작업을 하는 경우가 이에 해당합니다. 즉, ADO.NET에서는 메타데이터를 다룰 때 XML을 직접 사용합니다.

데이터 집합은 XML로 표시됩니다. 데이터 집합의 구조(데이터 집합에 있는 테이블, 열, 데이터 형식, 제약 조건 등의 정의)는 XSD(XML 스키마 정의 언어)를 기초로 한 XML 스키마를 사용하여 정의됩니다. 데이터 집합에 포함된 데이터를 XML에서 로드하고 XML로 serialize할 수 있는 것처럼, 데이터 집합의 구조도 XML 스키마에서 로드하고 XML 스키마로 serialize할 수 있습니다.

ADO.NET에서 데이터를 사용하는 작업의 경우 스키마에 대해 깊이 알 필요는 없습니다. 대개 Visual Studio .NET 도구에서는 비주얼 디자이너에서 수행한 작업을 기반으로 필요에 따라 스키마를 생성하고 업데이트합니다. 예를 들어, 이 도구를 사용하여 데이터베이스의 테이블을 나타내는 데이터 집합을 만드는 경우 Visual Studio .NET에서 데이터 집합의 구조를 나타내는 XML 스키마를 생성합니다. 그런 다음 XML 스키마는 형식화된 데이터 집합을 생성하는 데 사용됩니다. 형식화된 데이터 집합에서 테이블, 열 등의 데이터 요소를 첫 클래스 멤버로 사용할 수 있습니다. 형식화된 데이터 집합에 대한 자세한 내용은 데이터 집합 소개를 참조하십시오.

그러나 스키마를 직접 만들거나 편집해야 할 수도 있습니다. 일반적인 예로 협력업체나 고객과 함께 스키마를 개발하는 경우가 있습니다. 이 경우에 스키마는 교환할 XML 기반 데이터의 구조와 관련하여 사용자와 협력업체 사이의 계약 역할을 합니다. 이러한 상황에서는 종종 스키마 요소를 사용자의 데이터베이스 구조에 매핑해야 합니다. 스키마를 디자인하는 방법에 대한 자세한 내용은 XML 스키마 및 데이터를 참조하십시오.

ADO.NET의 구성 요소

다음 그림은 ADO.NET 응용 프로그램의 주요 구성 요소를 보여 줍니다.

ADO.NET 데이터 구성 요소

다음 표에서는 위에서 설명된 ADO.NET의 데이터 구성 요소를 요약하고 자세한 정보를 볼 수 있는 링크를 제공합니다.

구성 요소 또는 개체 자세한 내용
데이터 집합 데이터 집합 소개
데이터 어댑터 데이터 어댑터 소개
데이터 연결 ADO.NET 연결 디자인 도구 소개
Windows Form Windows Forms 소개
Web Forms 페이지 Web Forms 페이지 소개
BizTalk BizTalk Web page (https://www.microsoft.com/biztalk)

참고 항목

ADO.NET의 장점 | ADO.NET과 ADO 비교 | ADO.NET 데이터 집합 | ADO.NET 데이터 어댑터 | ADO.NET을 사용하여 데이터 액세스 | Visual Studio에서의 XML | XML 스키마 및 데이터