3티어에 대한 이야기를 적어 볼까 했는데
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1582&page=1
바로 아래에 글이 적혔다. 여러모로 감사함을 전한다.
^^;;
촌장의 눈치가 계속 보이는 덕에 이번 강좌에는 C#코드를 조금 넣어보도록 하자.
계속 낙서만 적다가는 내가 적은글들이 모두 자게로 갈듯 하다.
프레임웍에는 빠지기 어려운것중 하나가 DB 컨넥션일것이다.
DB연결하는 클래스를 간단하게 만들어 보자.
처음 DB에 연결을 하기 위한 요구사항은
1. 오라클이 되고
2. ms-sql이 되며
3. sql 로 코딩이 가능하고
4. Sp로도 코딩이 가능하고 싶다.
하여간.. 자유로운 영혼이길 바랄것이다.
그러한 코딩을 해보도록 하자.
단지 여기서 코딩하는 기법은 정상적이라기 보다는..
비정상적인것에 가까울수도 있고 되도록 소스를.. 안정적(?)이기
보다는 짧게 가는방향을 선택할것이다.
여하튼 시작해 보자.
일단 클래스 디자인은.
이런모습이 일단 나올것이다. 아래의 setDB는 생성자이니.
기본적으로 callSP와 callSQL형태의 두개의 매서드가 존재한다.
기능이야 알고 있듯이 sql넣어서 실행하고 하나는 SP를 호출해서
실행할것이다.
3.5의 링쿠는.. 지금 다루어야 되는 부분이 아니라고 생각하니까. 일단은 2.0
을 기준으로 계속 가도록 하자.
여러가지 형태가 있겠지만. 우리는 간단하게 뭔가의 쿼리를 때리고 결과치를 받기만 하면된다. 물론 조금 더 있다가는 입력하는것도 하겠지만.. 지금은 심풀하게 쿼리내용을 데이타셋으로 받는것에 집중하자.
---------------------------------------------------------------------------------------------
기본적으로 말이다.
닷넷은.. 값을 하나만들고 오는 함수와 reader같은것도 있고
dataset을 채우는것들이 있다.
여기서 우리는 뜬금없이.. 자전거와 오토바이 그리고 자동차에 대해서 이야기를 해보자.
A지역에서 B지역으로 물건을 옮기는데 거리가 100미터라고 생각을 해보자.
가끔 우리는 자전거로 가기가 편한곳이 있고 주차문제로 오토바이를 타기가 유용할때도 있으며
그래도 옮겨야 되는 물건이 많다면 당연히 자동차를 타야한다.
하지만 결론적으로 모든것이 가능한것은 자동차일것이다.
하지만 어떻는가 덩치가 크고 다시 세워두어야 하니 여러모로 귀차니즘이 발생한다.
하지만 반대로 작은데이타던지 큰 데이타던지 무관하게 자동차를 모두 이용하게 한다면 사용자 측면에서는 단일한 인터페이스(?)를 유지시킬수 있을것이다.
물론 어떤업무인가에 따라 많은 모습이 변화되겠지만. 결론적으로 우리가 지금 구상하고 있는 테스트 프로그램에서는
단일한 인터페이스인 자동차(?)를 유지해 보도록 하자.
이말은... 무조건 쿼리를 날리고 dataset 을 얻어오는것을 기본으로 하겠다는 이야기다.
계속 모습이 변하겠지만.. 기본적인 형태를 코딩을 하면
이런 모습을.. 예상할수도 있을것이다.
아니 이런것들로 시작을 하면 머리가 아플듯 하니 일단은 사용에 대해서 좀 더 초점을 두고 구현은 나중에 살펴 보도록 하자.
실제적으로 위의 내용을 잘~~~ 설명을 하자면 우리는 기본적으로
"생성자패턴" 이라고 하는것들에 대해서 한번쯤 이야기를 해야 되기 때문이다.
물론 내가 여기서 가벼운 싱글톤 패턴정도야 이야기 해줄 수 있긴해도 왜 팩토리 패턴이 어쩌고를 떠들게 되고
3티어라던지에 대한 잡설을 펼치게 되었다가는 아마도 너무 코드없는 이야기가 될수도 있기 때문이라고 위안을 삼자.
(당연히 난 모르면서 아는척 하는데 거의 상승의 경지에 이르렀다.)
사용을 어떻게 할것인가가
실제적인 구현에 영향을 미칠것이니.. 우리의 사용법을 편리하게 하는것에 집중을 하자.
--------------------------------------------
우리가 클래스를 만들고 객체지향(?)이라는 허접한 단어를 남발하면서 코딩을 하는 이유는 머리쓰기가 싫어서 이다.
클래스를 만드는 이유는 그 자체가 머리를 어떻게 하면 더 안쓰고(?) 코딩을 할까를 머리쓰다가 만든게 그 이유다.
모순인가?.. 머리를 쓰지 않기 위해서 클래스를 머리쓰면서 만드는거 말이다.
세상이 뭐 다 그런거 아니겠는가?
요구사항
자.. DB를 접속을 하고는 싶다.
근데 귀찮다. 그냥 대충 결론적으로 DataSet만 가지고 오고싶다.
입력할것은 select * from 주저리 주저리만 입력하면 알아서 가져오면 좋겠다.
아.. 가끔 sp도 써야 하니.. 이것도.. 인자값만 넣으면.. 알아서 dataset을 가져오면 좋겠다.
아.. 오라클도 되고 ms-sql도 되면 좋겠다.
이정도만 되면.. 좋은거 아닌가?
자.. 위의 요구사항을.. 정리를 하면.. 생성자에 DB가 오라클인지 ms-sql인지를 넣고
Sp호출을 하던지 sql를 넘기면.. Dataset 을 돌려주는 클래스를 설계를 하면
아마도 이렇게 될듯 싶다.
뭘 이딴걸 만들고 있냐고 또 한소리 하는 사람이 있을듯 하여 계속 말하지만.
사용법은
setDB DB = new setDB("Oracle");
dataGridView1.DataSource = DB.callSQL("select * from tab").Tables[0] ;
이렇게 두줄 적으면..그냥 이유없이.. 데이터
이렇게 될것이라는 거다.
당연히 sql를 두줄로 이렇게 적으면..
setDB DB = new setDB("Oracle");
dataGridView1.DataSource = DB.callSQL("select * from tab").Tables[0] ;
dataGridView2.DataSource = DB.callSQL("select * from emp").Tables[0];
이렇게 된다는것이다.
즉.. 귀찮게 뭔가를 하지 않아도 결과만 가져오기 위해서 우리는..
클래스를 만든다.
그럼.. MS-sql은 어떻게 할까?
setDB DB = new setDB("MS");
dataGridView1.DataSource = DB.callSQL("select * from comboboxt").Tables[0] ;
위와 동일하게 적어주면.. 된다.
모든게 동일하니.. 우리는 쉽게 setDB에 단지 인자값만 조정해 주면 되는것이다.
그럼.. SP는 어떻게 할까?를 또 고민해야 하는데.
이건 인자값을 일단 받아야 한다. 그것을 모두 string으로 통일하는 입장을 가지도록 하자. 왜냐면 나는 당신에게 솔류션을 제공하는게 아니기 때문이다.
그리고 대부분의 경우(80~90%)는 string으로 모든걸 처리하는게 편하다.
예를들어서..
CREATE PROCEDURE yun_test
@one char(12),
@two char(12)
AS
BEGIN
select * from comboboxt where viewseq <> @one
END
이런 sp를 작성했다고 하자. 물론 @two는 사용하지 않지만 인자값을 여러 개 넘기는것을 테스트 하는 모습을 보여주기 위해서 이다.
이것은 이렇게 호출하도록 하자.
setDB DB = new setDB("MS");
Dictionary<string, string> para = new Dictionary<string, string>();
dataGridView1.DataSource = DB.callSQL("select * from comboboxt").Tables[0] ;
para["@one"] = "1";
para["@two"] = "2";
dataGridView2.DataSource = DB.callSP("yun_test", para).Tables[0];
다소 길어졌다.
하여간 이정도면.. 나름대로 ms와 오라클을 쓰고 그리고 sql로도 가능하며
SP도 가능한 편한 클래스라고 생각한다.
아마도 누군가.. 왜 datatable를 사용하지 않고 dataset을 사용했는가를 딴지를 걸수도 있을것 같다.
이런것은 이미 다 말하지 않아도 알것 같긴하지만 그래도 굳이 설명을 한다면
(설명하기 전부터 막 귀찮아 지고 있다.)
예를 들어서 SP를..
ALTER PROCEDURE [dbo].[yun_test]
@one char(12),
@two char(12)
AS
BEGIN
select * from comboboxt where viewseq <> @one;
select * from comboboxt ;
END
이런식으로 바꾸었다고 하자.. 두개의 쿼리문장이 있다면 저것을 한번에 받을때 어떻게 받을것인가?
그렇다. 그래서 데이터 셋으로 받는다.
이런경우는 생각외로 드물게 일어나므로(10%정도) 클래스는 그냥 일반적인 형태로 디자인 하고 있다.
아.. 오라클도 해야되나. ㅠ.ㅠ
오라클을 보자.
오라클은..짜증만땅이다.
나름대로 뭔가를 잘 지켜줘야 하기도 하고 나름대로 괜찮기도 하면서 또 나름대로 피곤하다.
DB로는 참 괜찮다.
연결적인느낌으로는 피곤하다.
를 이야기 할수 있다.
일단… 오라클의 경우 SP호출시 커서로 받아야 되어야 인자값이 늘어나야 한다.
para["one"] = "1";
para["two"] = "2";
para["o_rc"] = "";
para["o_rc2"] = "";
이런식으로 증가하게 될것이다. 받아야 되는 커서를 넣어야 한다.
여기서 "O_"로 시작하면 커서타입으로 되도록 클래스내에 약속을 지정했다.
그리고 SP에도 이것들을 다 설정해야 하는데
CREATE OR REPLACE package types
as
Type cursorType is ref cursor;
end;
형태로 선언을 처리하고..
-------------------------------------------------------
CREATE OR REPLACE procedure yun_test
(
one in varchar,
two in varchar,
o_rc out types.cursortype,
o_rc2 out types.cursortype
)
is
begin
open o_rc for
select * from emp where sal like '%' || one || '%';
open o_rc2 for
select * from emp ;
end;
이런 형태로 커서를 열어주고 처리를 해야한다.
그래서 ms쪽 책을 보면 커서를 사용하지 말라는 이야기를 적어둔게 있던데
DB의 차이 때문에 그런말이 나온듯 하다.
사용법은 동일하다.
setDB DB = new setDB("oracle");
Dictionary<string, string> para = new Dictionary<string, string>();
para["one"] = "1";
para["two"] = "2";
para["o_rc"] = "";
para["o_rc2"] = "";
dataGridView1.DataSource = DB.callSP("yun_test", para).Tables[0];
dataGridView2.DataSource = DB.callSP("yun_test", para).Tables[1];
물론 저렇게 적어서 두번이나.. 디비를 굴리는 코딩은 하지 않을것이라 믿는다.
이건 예제이므로 용서해다오.. 두어줄 더 적는것도 귀찮다.
하여간.. Sp에서 많은 커서를 넘긴다면.. Dataset을 public으로 하나 두는것도 좋을듯 싶다.
지금은 그렇게 하지 않는다.
물론 세부적인 세세한 것을 더 작성한다면 더욱좋겠지만.. -_-;; (이건 솔류션이 아니라고 …~~~~!!! 단지 낙서야 낙서)
테이블이름을 매칭을 시킨다던지 하는것들 말이다. 그런건 알아서 하기 바란다.
개인적인 이야기지만 대략 지금의 기능을 구현하는데 클래스 하나에 100여줄 코딩으로 끝나지만..
세세한 기능을 다 주고 에러처리에 몇몇가지를 추가하면 여러가지 클래스를 만들어야 하며 몇몇가지 Adapter적인것과 Interface적인 녀석까지 추가해서 만든다면 전체 코딩이 1000여줄이 넘어설것이다.
그러니 그냥 가자.
간단히 가기위한 몇몇가지 방책들..
1.
심풀하게 이녀석은 singleton도 구현하지 말고 그냥.. 무식하게 static connection 하나로 버팅기는 식으로 코딩을 하자.
2.
낙서에는 기본적으로 try ~ catch같은걸 적는걸 배제하는 이유는 소스가 길어지기 때문이다.
3.
인자값은 무조건 스트링 리턴값은 무조건 데이타셋이다.
에러가 뜬다면.. 질답란에 질문을 하면
답변을 달아줄 사람이 부지기수니 잘 물어보기만 하면 될것이다.
저짝에 벌써 손들고 SP에 인자값 없어도 되는 오버로딩도 하나 추가해달라는 사람이 보인다. 그런건.. 제~ 발 알아서 하기 바란다.
원본 위치 <http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1583&page=2>
'C# DB 코딩 강좌' 카테고리의 다른 글
C#을 이용한 DB코딩 10 (0) | 2008.11.14 |
---|---|
C#을 이용한 DB코딩 9(인터페이스) (0) | 2008.11.14 |
C#을 이용한 DB코딩 8 (0) | 2008.11.14 |
C#을 이용한 DB코딩 7 (0) | 2008.11.14 |
C#을 이용한 DB코딩 6(TcpChannel) (1) | 2008.11.14 |
C#을 이용한 DB코딩 4(Virtual PC) (0) | 2008.11.14 |
C#을 이용한 DB코딩 3 (0) | 2008.11.14 |
C#을 이용한 DB코딩 2 (0) | 2008.11.14 |
C#을 이용한 DB코딩 1 (0) | 2008.11.14 |
DB 이야기를 시작하면서 (0) | 2008.11.14 |