사용자 도구

사이트 도구


사이드바

카테고리

db:adonet프로그래밍

ADO.NET 아키텍쳐

쓰다보니 msdn 요약판이 되어버리고 있는데, 그만큼 내용이 많음

구성요소

  1. .NET framework data provider : 개체 콜렉션을 말하는건지, 개념인지 모르겠다.
    • Connection 개체 : DB에 연결
    • Command 개체 : DB에 SQL,SP 실행
    • DataReader : Command결과를 리턴 받기 - 단순 실행 후 결고 받기
    • DataAdapter : DataSet과 실제 데이터 소스를 연결해준다. 직접 사용하지 않음? 아마?
  2. DataSet
    • DataSet : 실제 데이터와 연결해주는 역할. 로컬/xml/원격 데이터를 가리지 않고 연결 가능.
      사용 시기 : 데이터 조작이 필요한 경우, 폼에 바인딩이 필요한 경우

ADO.NET 아키텍쳐 (from MSDN)

DataReader냐 DataSet냐 선택하는 기준은 모호하지만, 보통의 경우라면 단순쿼리 결과만을 사용하고 싶을테니 DataReader가 바람직해 보임.

XML

  • DataSet이 XML을 매개로 데이터를 읽고 쓰기가 가능.
  • 웹에서 유용하게 사용하는듯.
  • 일반 응용프로그램에서도 XML을 DB의 캐쉬용도로 사용할 수 있다면 꽤 유용할듯.

응 그렇군 하는 부분인데 되려 적어 놓으려니 어색하네.

.NET framework data provider

DB에 연결/명령을 실행/결과를 검색하는데 사용되는 개체들.

  • 바로 결과를 보거나 : DataReader 사용
  • 다른 곳에 저장, 또는 데이터 이전등 재가공 : DataSet

데이터 공급자

  • .NET Framework Data Provider for SQL Server
  • .NET Framework Data Provider for OLE DB
  • .NET Framework Data Provider for ODBC
  • .NET Framework Data Provider for Oracle

MySql은 외부 Framework 사용

핵심개체

Connection 연결
Command 명령어
DataReader 실행과 결과
DataAdapter 데이터와 DataSet과 연결

그리고

Transation
CommandBuilder Command 개체의 Parameters 컬렉션을 채우는 도우미 개체
ConnectionStringBuilder Connection 개체에서 사용하는 연결 문자열을 만들고 관리할 수 있는 개체
Parameter 명령과 SP에 대한 입/출/반환값 매개변수 정의
Excpetion
Error
ClientPermission

데이터 공급자(Provider)의 선택

SQL Server “MSSql Server 7.0 ≤” 시 또는 단일 프로그램의 경우 사용 권장
OLE DB “MSSql Server 6.5 ≥” 시 또는 MSAccess DB 사용시 권장

나머지는 이름대로.

연결 풀링 : Connection Pool

설명 : MSDN 연결풀링사용

  • default : 연결풀링 사용
  • DB 서버에 연결하는 것은 시간이 많이 걸린다.
  • ADO.NET에선, 연결 회수를 최소화하기 위해 “연결풀링”을 내부에서 구현한다.
  • Connection::Open 을 실행시, 사용 가능한 연결을 확인하고 사용 없으면 새로 개설
  • Connection::Close 실행시, 실제로 클로징 하는 것이 아니라 풀링 연결 집합에 반환. 다시 Open시 재활용
  • 커넥션풀을 따로 구현할 필요는 없다. (벤치마킹은 안해봐서 모르지만)

풀링 집합의 규칙

  • 기준이 되는 구성마다 여러 개의 풀을 동시에 유지.
  • 연결은 연결문자열(ConnectionString) 기준으로 풀을 나누게 됨. ← 내가 쓰려는 쪽
  • 통합 보안을 사용하는 경우, WindowsID를 기준으로 함

만들기 및 할당

// using을 사용해서, using 구문 안에서만 커넥션(연결)을 사용하고 close한다.
using( SqlConnection connection = 
        new SqlConnection("Integrated Security=SSPI;Initial Catalog=Northwind") )
{
    connection.Open(); // Pool A is created.
}

연결문자열에 MinPoolSize가 1 이상이면, 프로세스 종료시까지 연결풀이 남아 있게 된다. 반대의 경우, 비활성 기간(아래참고) 후에 연결은 모두 닫힌다.

연결추가

  • 연결문자열에 대해서 풀이 만들어짐 ( 최대풀크기미만(>100)으로 생성 )
  • 연결풀러는 연결이 풀로 회수 될때, 재할당하여 연결 요청 처리.
    • 풀에 여분이 없는 경우, 15초 대기.
    • 15초가 지나면 예외 처리
사용 종료시, 풀로 반환 되도록 닫을 것. 닫기 위해서는
  • Connection의 Close 또는 Dispose 를 사용
  • c#의 using 문 내에서 연결을 열어 사용하면 됨
  • 직접 작성한 클래스에서 해제할 수 있는 리소스가 있는 경우에만 Finalize 사용할 것
  • Connection, DataReader 의 Close/Dispose를 자신의 클래스 Finalize에서 호출하지 말 것

연결제거

  • 연결 풀러가 주기적으로 미사용 연결을 회수지만, 시간이 많이 걸리므로
  • 사용 후에는 Close/Dispose를 호출해 줄 것
  • 연결이 끊긴 (네트워크에 없는) 연결은 사용하게 될 수도 있다. 이 때 연결이 유효한지 확인하는 오버헤드가 발생된다. 사용실패 시에는 예외가 발생

풀제거

트랜잭션 지원

풀이 닫히더라도 트랜잭션이 진행/보류 중인 연결에 재 연결 되도록 내부 처리 된다고 한다.

연결문자열을 사용한 풀링제어

ConnectionString을 통해 연결풀링 로직 조정 가능

링크로 연결된 사이트에 사용가능한 옵션이 자세히 나와 있지만 몇가지 정리

설명

OLE DB와 비슷해 보이지만, 약간 다르다네.(한가지인가봐)

  • Persist Security Info == false면 보안 정보를 제외한 설정이 ConnectionString과 같음
  • .net framework data provider for SQL server는 Persist Security Info == true 일때만 문자열 암호 유지

그리고

  • SqlConnectionStringBuilder로 올바른 런타임 연결 문자 생성을 추천
  • 닫힌 연결 상태에서면 속성 설정 가능
  • 로컬 컴퓨터는 “(local)“이라고 입력
    • “ip,port” 형식으로 입력
  • 구문 분석은 설정 후 바로 진행. 예외는 ArgumentException 로 리턴
  • 다른 오류는 연결시 확인 (아이피나 암호 같은건 연결해봐야 알테니)

형식

  • keyword=value
  • 문자열에 공백( )/세미콜론(;)/작은따옴표(')/큰따옴표(”)을 넣고 싶으면 ”(이 안에 넣기)“ 를 사용할 것
    • 예 : server=“I'mNiceGuyServer”
  • 첫문자 아닌 경우 ” 나 ' 를 문자열 중간에 추가 가능
    • 예: Data Source= my'Server 또는 Data Source= my“Server
  • 키워드나 값에 등호( = )를 넣으려면 ( == ) 처럼 등호를 하나 더 사용할 것
    • 예 : “key==word=value”
    • key(key=word) / value(value)
  • 키워드는 대소문자 구문 없음

키워드

보통 사용하는 것들

Server 연결할 SQL 인스턴스나 네트워크 주소
server=tcp:servername, port
Data Source
Address
Network Address
Addr
database 데이터베이스 이름
Initial Catalog
Connect Timeout 이름 그대로, 초단위
User ID 이름 그대로
Password or Pwd 이름 그대로
Persist Security Info false : 암호와 같은 정보는 다시 리턴되지 않음 (default)

그외

Trusted_Connection true : 윈도우즈 계정 로그인
false : 아이디 암호로 로그인
Network Library 연결 프로토콜
default –> dbmssocn(TCP/IP), dbnmpntw(명명된 파이프), dbmsrpcn(멀티프로토콜), dbmsadsn(Apple Talk), dbmsgnet(VIA), dbmslpcn(공유 메모리), dbmsspxn(IPX/SPX)
Net
Integrated Security
Asynch 비동기 지원 (true or false)
AttachDBFilename 사용할 DB 파일명
Initial File Name
Encrypt 서버에 인증서가 설치되어 있고, https 통신을 할 경우
Type System Version 서버에 맞는 문자열 값 사용
Type System Version=SQL Server 2000;
Type System Version=SQL Server 2005;
Type System Version=Latest;

연결 풀링에 대한 것

키워드 기본값 설명
Pooling true 풀링 사용 여부
Connection Lifetime 0 == 최대연결시간제한 반환시 ((현재시간-만든시간)초 < Connection Lifetime초) 이면 삭제
Connection Reset true 풀에서 제거될때 연결이 다시 설정되는가? 아니면 리셋되는가
Enlist true true면 현재 트랜잭션 컨텍스트에 자동 연결,참여
Load Balance Timeout 0 연결풀에서 연결이 소멸되기까지 시간(초)
Max Pool Size 100 이름 그대로
Min Pool Size 0 이름 그대로

풀단편화

(상황)

  • 단일 서버에서 여러 웹사이트 호스팅,
  • 그리고 단일 DB 사용해서 폼 인증 로그인 확인 후 특정 데이터베이스 연결
  • 폼 인증시 사용된 dB는 한번 열린 연결(Connection)을 재사용/공유
  • 하지만 사이트마다 각각 개별 DB에 대한 연결은 늘어나므루 서버에 대한 연결 수 증가

(정리)

  • 각 사이트가 다른 DB에 연결하면 연결 개수가 증가

(팁)

  • master 디비에 연결 (새로 열린 연결을 공유)
  • USE문을 사용해서 원하는 디비로 변경 후 작업 진행

이렇게 하면 연결 수를 줄일 수 있다. 근데 보안은?

명령사용

  • 관련개체 : Command / Transaction / CreateCommand / CommandText
  • 주요 사용 방식 : SQL 실행 / SP 실행 / 자동 생성 명령어? / 단일값 가져오기

명령실행(SQL 실행)

SP 실행

개요

  • SQL문처럼 전달하면 간단히 호출 가능
  • DbCommand + Parameters 컬렉션 사용시 : 출력갑 + 반환값 사용 가능

방식

  • Command의 CommandType을 StoredProcedure로 설정
  • Parameters 컬렉션에 파라미터 입력

기본예제

// Assumes that connection is a valid SqlConnection object.
 
SqlCommand salesCommand = new SqlCommand("SalesByCategory",connection);
salesCommand.CommandType = CommandType.StoredProcedure;
 
// 파라미터 타입 설정 후, 값 대입
// 널이 경우 DBNull.Value를 대입
SqlParameter parameter = 
    salesCommand.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15);
parameter.Value = "Beverages";
 
connection.Open();
 
SqlDataReader reader = salesCommand.ExecuteReader();
 
Console.WriteLine("{0}, {1}", reader.GetName(0), reader.GetName(1));
 
while (reader.Read()) {
    Console.WriteLine("{0}, ${1}", reader.GetString(0), reader.GetDecimal(1));
}
 
reader.Close();
connection.Close();

InputOutput / Output / ReturnValue 형식 지정

Output 과 ReturnValue 를 받고 사용하는 방법 참고

// Assumes that connection is a valid SqlConnection object.
SqlCommand command = new SqlCommand("SampleProc", connection);
command.CommandType = CommandType.StoredProcedure;
 
SqlParameter parameter = command.Parameters.Add("RETURN_VALUE", SqlDbType.Int);
parameter.Direction = ParameterDirection.ReturnValue;
 
parameter = command.Parameters.Add("@InputParm", SqlDbType.NVarChar, 12);
parameter.Value = "Sample Value";
 
parameter = command.Parameters.Add("@OutputParm", SqlDbType.NVarChar, 28);
parameter.Direction = ParameterDirection.Output;
 
connection.Open();
 
SqlDataReader reader = command.ExecuteReader();
 
Console.WriteLine("{0}, {1}", reader.GetName(0), reader.GetName(1));
 
while (reader.Read()) {
  Console.WriteLine("{0}, {1}", reader.GetInt32(0), reader.GetString(1));
}
 
reader.Close();
connection.Close();
 
Console.WriteLine(" @OutputParm: {0}", command.Parameters["@OutputParm"].Value);
Console.WriteLine("RETURN_VALUE: {0}", command.Parameters["RETURN_VALUE"].Value);

나머지 타입의 예제는 MSDN 참조

파라미터 사용시 유의사항

sqlCommand (Data Provider for SQL Server)

  • 파라미터의 이름이 SP의 것과 동일 해야함 ( 뭐 이런.. 경우가 -_- )
  • ”?“를 사용하지 않음

OleDbCommand / OdbcCommand (Data Provider for OLE DB / ODBC)

  • 파라미터의 순서가 SP의 순서와 동일 해야함
  • 파라미터가 들어가는 곳에는 ”?“를 사용.
SELECT * FROM Customers WHERE CustomerID = ?

빠른 예

사용할 네임스페이스

using System.Data;
using System.Data.OleDb;

연결하고 SQL을 실행해 볼 수 있는 빠른 example

string _connstr = 
    @"Provider=SQLOLEDB.1;" + 
    "Data Source=ip,port;" + 
    "Initial Catalog=DB-Name;" + 
    "User Id=ID-string;" + 
    "Password=Password-IfItis;";
 
OleDbConnection _dbConn = new OleDbConnection( _connstr );
OleDbCommand    _cmd    = _dbConn.CreateCommand();
 
_dbConn.Open(); // 실제 연결 시도. try catch 블럭으로 실패 하는 경우 잡아낼 것
 
_cmd.CommandText        = @"select * from SomeTable";
OleDbDataReader reader  = _cmd.ExecuteReader();
 
while( reader.Read() ) // 결과가 있다면 말이지..
{
    Console.WriteLine( "\t{0}\t{1}", reader[0], reader[1] );
}
 
// 클린 부분은 나중에

링크들

db/adonet프로그래밍.txt · 마지막으로 수정됨: 2012/04/21 12:43 (바깥 편집)