훗. 오랜만에 강좌를 올리게 됐습니다. 근데 ASP.NET 프론티어 주제에 왜 여기다 강좌 올리냐구요?

그냥.


은 아니고 오늘 제가 웹 개발시 뿐만 아니라 어떤 프로그램 개발에서도 데이터 관리에 날개를 달아드리기 위해 이 강좌를 씁니다.

오늘 소개할 프레임워크는 바로 Simple.Data 입니다.

네임스페이스냐구요? 네 맞아요. 프로젝트명도 이래요.

이름답게 데이터 관리가 정말 쉽다는 겁니다.

어떻게? 직접 시연을 해드리죠.


프로젝트 주소는 다음과 같습니다. https://github.com/markrendle/Simple.Data

대세는 Git 입니다.ㅋ


쉽게 깔고 싶으시다면 Nuget 으로 Simple.Data 검색하고 받으면 끝납니다.

이 프레임워크는 System.Dynamic 을 이용하기 때문에 .NET 4 이상에서 동작합니다.

수동으로 깔고자 한다면 프로젝트 주소로 가서 Download 탭에 가셔서 최신 .zip 파일을 다운받으면 됩니다.

이 프레임워크는 Mono 2.10 이상에서도 지원됩니다.


데이터를 관리하는 프레임워크기 때문에 왠만한 DB 지원합니다.

지원하는 DB 목록은 다음과 같습니다.


  • ADO.NET 기반 데이터베이스 공급자
    • SQL Server 2005 이상
    • SQL Server Compact Edition 4.0
    • Oracle
    • MySQL 4.0 이상
    • SQLite
  • MongoDB

No-SQL 중에서는 MongoDB를 지원합니다.

하지만 저는 여전히 SQL 기반 DB 활용이 많기 때문에 SQL 기반 DB로 강좌를 올립니다.

PostgreSQL 및 Azure Table Storage 도 지원 예정이라 합니다. 애저에 목마르신 김대우 형님 주목!


자 이제 어떻게 쓰는지 알아보도록 하겠습니다.

마침 MSSQL 2008 R2가 깔려 있더군요. 내컴 말고요.

그래서 MSSQL로 진행하고자 합니다.

Nuget 으로 까시는 분들은 Simple.Data.SqlServer 를 깔아주시면 됩니다.

다른 DB라면 지원하는 DB 확인하시고 찾아주시면 되겠습니다.

수동으로 까신 분은 다운받은 어셈블리를 프로젝트에 추가하시면 됩니다. 다운받은 파일에 다 있습니다.


예제 데이터로 쓸 PRODUCTS 테이블입니다.

sshot-1.png


자 이제 시작해볼까요?


  1. @{
  2.     var db = Simple.Data.Database.OpenConnection("data source=서버주소;initial catalog=DB명;integrated security=false;User ID=아디;Password=비번");
  3.     var result= db.PRODUCTS.FindByGDSCD("T0001");
  4. }
  5. T0001의 제품명은 @result.GDSNM 입니다.


데이터베이스에 연결하였습니다. 저같은 경우 Razor 로 예제를 보여줬는데 C#으로 옮기고 싶다면 @{ ... } 부분을 복사하시면 되겠습니다.

저렇게 했더니 결과는 이렇게 나왔습니다. 성공적으로.

sshot-2.png 

T0001의 제품명을 주목해주세요. 그 코드 결과물입니다.


첫번째 라인에 보면 db 변수에 연결 문자열 보이시죠? web.config 에 정의된 것도 불러올 수 있습니다. 일단 빠르게 학습하기 위해서 이걸 쓴거죠.

using 문으로 Simple.Data 를 추가했는데도 저 네임스페이스 다 쓸수밖에 없는 왜냐면 하필

WebMatrix.Data.Database

이놈하고 중복된다고 합니다. 흑..

어쨌든 Simple.Data.Database 로부터 시작된다는 사실. 잊지마세요.


이렇게 해서 OpenConnection 으로 연결을 활성화합니다. 받는 파라미터는 연결 문자열입니다. web.config 거 받아와도 됩니다.

자, 이제부터 시작입니다. 이제부터 인텔리센스에 맡기면 안됩니다. 커넥션 메서드는 모두 dynamic 을 반환합니다.

런타임이 알아서 해석한다는 거죠. 결국 감(?)으로 코딩해야 하는 겁니다. 그렇다고 어려워하지 마세요. 규칙은 지키라고 있는겁니다.

간단하게 SELECT 문 부터 들어가도록 하겠습니다. 자. db 변수를 통해 DB 연결을 받았습니다. 이제 질의문 날려야죠?

db 부터는 dynamic 입니다. 하지만 정의한 규칙이 있습니다. SELECT문 규칙은 이렇습니다.

db.[테이블명].[where규칙].[orderby규칙]


규칙은 메서드로 이루어져 있으며, 테이블명은 속성으로 이루어져 있습니다. 그래서 테이블명을 정의하고자 한다면

db.PRODUCTS


이렇게 하면 됩니다. SQL 구문 특성상 대소문자 구분 안해도 됩니다. 편하게 하세요.

그리고 이제 특정 ID를 뽑기 위하여 PK 로 지정된 GDSCD 를 하나 뽑아보았습니다.

db.PRODUCTS.FindByGDSCD("T0001");


FindBy가 where 절 역할을 담당합니다. 단, FindBy 접두사는 대소문자 구분하니 이에 주의하시면 되고,

FindBy 뒤에 붙는 칼럼명은 그냥 칼럼명 편하게 쓰시면 되겠습니다.

또한, 메서드 형태로 진행되어 인자를 넣는 형식으로 진행되겠습니다.

또는 이런 식으로도 똑같은 결과를 나오게 할 수 있습니다.

db.PRODUCTS.FindBy(GDSCD:"T0001");


바로 파라미터 이름을 명시적으로 지정해서 똑같은 필터링 효과를 낼 수 있죠.

지금 2가지는 다음 SQL문과 같습니다.

SELECT * FROM PRODUCTS WHERE GDSCD='T001'


위 방법의 경우라면 만약 필터링할 칼럼이 2개 이상이면 유용하겠습니다.

db.PRODUCTS.FindBy(GDSFG: "Y", EMAIL: "test@test.com");


자. 지금까지 이렇게 하셨으면, 결과는 받아야죠? FindBy 는 한 개의 행을 반환합니다. 행 데이터도 dynamic 입니다. ㅋㅋㅋㅋ

받았으면 result 변수로 받아서 그냥 써먹는 겁니다.

var result = db.PRODUCTS.FindBy(GDSCD:"T0001");Console.Write("T0001 상품명은 {0} 입니다.",result.GDSNM);

속성명은 칼럼명을 사용한다고 보면 되겠습니다. 끝. 참 쉽죠?

또한, 캐스팅도 지원합니다. 만약 POJO 나 iBatis 에 쓰이는 DTO 등의 데이터 정의 클래스를 만드셨다면, 그 클래스로 캐스팅하셔도 됩니다.

Product result = (Product)db.PRODUCTS.FindBy(GDSCD:"T0001");


그럼 해당 클래스로 칼럼명 확인하고 유효하면 캐스팅이 성공할 거고, 그대로 써먹어 주시면 되겠습니다.


이제 2개 이상의 행을 가져올 시간. 필터링 규칙은 다를 건 없습니다. 단, 메서드명은 틀립니다. 바로 FindAllBy 되겠습니다.

이렇게 써도 되고

db.PRODUCTS.FindAllByEMAIL("test@test.com")


이렇게 써도 됩니다.

db.PRODUCTS.FindAllBy(EMAIL: "test@test.com")


결과는 똑같이 나옵니다. 생성된 SQL문도 똑같습니다.

SELECT * FROM PRODUCTS WHERE EMAIL='test@test.com'


FindAllBy는 IEnumerable<dynamic> 타입을 반환합니다.

그래서 foreach 문에 바로 써먹거나 Linq 구문을 바로 이용하시면 되겠습니다.

자. 이제 좀 더 다양하게 필터링 하는 방법을 알아보겠습니다.

이번에 알아볼 메서드는 Find 입니다. Find 는 단일 레코드고 FindAll 은 다중 레코드인 점만 아시면 되겠습니다.

자. 날짜가 올해 1월 25일 이후로 조회하고자 한다면? 이렇게 하시면 되겠습니다.

db.PRODUCTS.Find(db.PRODUCTS.REGDT >= "2012-01-25");


문자열에 >= 연산자 지원 안할거라 쫄지 마십시오. 저 문자열 날짜는 DATETIME 으로 캐스팅 시도를 합니다. DateTime 은 >= 같은 숫자 연산자도 지원되거든요. Linq 스타일이죠? Linq 처럼 이용하면 되지만 진짜 Linq는 아니라고 하더군요.

일단 연산자는 아래와 같은 방식이 지원됩니다.

  • ==
  • !=
  • <
  • <=
  • >
  • >=

SQL 에 쓰이는 연산자와 C# 연산자에 혼동하지 마세요. VB.NET 은 해당없을듯. <> 연산자도 지원되니..

BETWEEN 문도 지원됩니다. 예를 들어, 1월 10일부터 20일까지의 상품을 받고 싶다면 이렇게 하시면 되겠습니다.

db.PRODUCTS.FindAllByREGDT("2012-01-10".to("2012-01-20"));


그럼 SQL문으로는 이렇게 나옵니다.

SELECT * FROM PRODUCTS WHERE REGDT BETWEEN '2012-01-10' AND '2012-01-20'


그럼 Join 문도 지원되나요? 네.

어떻게요? 이렇게 하시면,

db.Customers.Find(db.Customers.Invoices.Paid == “N”)


SQL 문으로는 이렇게 나옵니다.

SELECT [Customers].* FROM [Customers] 
JOIN [Invoices] ON [Customers].[CustomerId] = [Invoices].[CustomerId]
WHERE [Invoices].[Paid] = @p1


물론 제약사항이 있습니다. 조인할 테이블 PK 칼럼이 조인받을 테이블에 있어야 하니까요.

마지막으로 필터링 없이 모든 데이터를 불러오고 싶다면. 그냥 All 메서드 쓰시면 됩니다.

db.PRODUCTS.All()


마지막으로 Order By 절. 필터링 또는 All 메서드 실행 후, OrderBy 메서드를 쓰시면 끝.

db.PRODUCTS.FindAllBy(EMAIL: "test@test.com").OrderByGDSNM();


또는

db.PRODUCTS.FindAllBy(EMAIL: "test@test.com").OrderBy(db.PRODUCTS.GDSNM);


이렇게 쓰면 SQL문은 이렇게 되겠습니다.

SELECT * FROM PRODUCTS WHERE EMAIL='test@test.com' ORDER BY GDSNM


자. SELECT 문에 대해서 알아봤습니다.

Simple.Data 의 구조는 의외로 간단합니다. Dynamic 구문을 이용하여 SQL 문을 생성하는 원리입니다.

또한 오픈소스이며, 엔티티 모델링 중 최고로 간단하기 때문에 주목을 받고 있습니다.

아직까지 복잡한 SQL 구문 이식이 지원되지는 않지만, 커뮤니티로 개발중에 있으며, 계속 활동해가면서 향상되고 있습니다.

다음 강좌에서는 삽입, 수정, 삭제를 알아보도록 하겠습니다.


끝. ㄳㄳ





profile
20대 언제나 쿨한 개발(犬足)자.