====== ADO.NET 아키텍쳐 ======
쓰다보니 msdn 요약판이 되어버리고 있는데, 그만큼 내용이 많음
===== 구성요소 =====
- .NET framework data provider : 개체 콜렉션을 말하는건지, 개념인지 모르겠다.
* Connection 개체 : DB에 연결
* Command 개체 : DB에 SQL,SP 실행
* DataReader : Command결과를 리턴 받기 - 단순 실행 후 결고 받기
* DataAdapter : DataSet과 실제 데이터 소스를 연결해준다. 직접 사용하지 않음? 아마?
- DataSet
* DataSet : 실제 데이터와 연결해주는 역할. 로컬/xml/원격 데이터를 가리지 않고 연결 가능.\\ 사용 시기 : 데이터 조작이 필요한 경우, 폼에 바인딩이 필요한 경우
{{:csharp:ado.net-arch.gif|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은 [[http://dev.mysql.com/downloads/connector/net/5.2.html|외부 Framework]] 사용
===== 핵심개체 =====
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbconnection(v=VS.80).aspx|Connection]] | 연결 |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbcommand(v=VS.80).aspx|Command]] | 명령어 |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbdatareader(v=VS.80).aspx|DataReader]] | 실행과 결과 |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbdataadapter(v=VS.80).aspx|DataAdapter]] | 데이터와 DataSet과 연결 |
그리고
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbtransaction(v=VS.80).aspx|Transation]] | |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbcommandbuilder(v=VS.80).aspx|CommandBuilder]] | Command 개체의 Parameters 컬렉션을 채우는 도우미 개체 |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbconnectionstringbuilder(v=VS.80).aspx|ConnectionStringBuilder]] | Connection 개체에서 사용하는 연결 문자열을 만들고 관리할 수 있는 개체 |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbparameter(v=VS.80).aspx|Parameter]] | 명령과 SP에 대한 입/출/반환값 매개변수 정의 |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbexception(v=VS.80).aspx|Excpetion]] | |
| Error | |
| [[http://msdn.microsoft.com/ko-kr/library/system.data.common.dbdatapermission(v=VS.80).aspx|ClientPermission]] | |
===== 데이터 공급자(Provider)의 선택 =====
| SQL Server | "MSSql Server 7.0 ≤" 시 또는 단일 프로그램의 경우 사용 권장 |
| OLE DB | "MSSql Server 6.5 ≥" 시 또는 MSAccess DB 사용시 권장 |
나머지는 이름대로.
====== 연결 풀링 : Connection Pool ======
설명 : [[http://msdn.microsoft.com/ko-kr/library/8xx3tyca(v=VS.80).aspx|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를 호출해 줄 것
* 연결이 끊긴 (네트워크에 없는) 연결은 사용하게 될 수도 있다. 이 때 연결이 유효한지 확인하는 오버헤드가 발생된다. 사용실패 시에는 예외가 발생
===== 풀제거 =====
* [[http://msdn.microsoft.com/ko-kr/library/system.data.sqlclient.sqlconnection.clearallpools(v=VS.80).aspx|ClearAllPools]] / [[http://msdn.microsoft.com/ko-kr/library/system.data.sqlclient.sqlconnection.clearpool(v=VS.80).aspx|ClearPool]]
===== 트랜잭션 지원 =====
풀이 닫히더라도 트랜잭션이 진행/보류 중인 연결에 재 연결 되도록 내부 처리 된다고 한다.
===== 연결문자열을 사용한 풀링제어 =====
[[http://msdn.microsoft.com/ko-kr/library/system.data.sqlclient.sqlconnection.connectionstring(v=VS.80).aspx|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] );
}
// 클린 부분은 나중에
====== 링크들 ======
* [[http://darby.wo.tc/blog/entry/C-C%EC%97%90%EC%84%9C-MySQL-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0|[C#] C#에서 MySQL 연동하기]]
* [[http://www.mybatis.org/|MyBatis]]
* [[http://msdn.microsoft.com/ko-kr/library/system.data.oledb(VS.80).aspx|System.Data.OleDb 네임스페이스]]
* [[http://msdn.microsoft.com/ko-kr/library/dw70f090(VS.80).aspx|ADO.NET 샘플 응용 프로그램]]
* {{:csharp:csharpDBconnection.ppt|c#에서db연동방법(ppt)}}
* [[http://mean79.tistory.com/144|MSSql 날짜 관련 함수]]
* [[http://sql.1keydata.com/kr/sql-insert-into.php|SQL 구문 설명 사이트]]