====== 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 구문 설명 사이트]]