• 카테고리
    • 전체 글

    • 카테고리1
    • 카테고리2
    • 카테고리3
    • 카테고리4
  • 태그
  • 방명록

'기술자료'에 해당되는 글 351건

  • 2009.12.26 Java의 웹 프로그래밍의 오해 from ASP.NET
  • 2009.12.22 [Google Apps Engine] Java SDK 설치하기.
  • 2009.12.22 [Google Apps Engine] 소개
  • 2009.12.21 Lotto 당첨번호 및 기타 정보 저장 서비스 제공 - Azure 버전
  • 2009.12.18 CloudQueueClient.GetQueueReference 의 인자값 문제.
  • 2009.12.17 TableServiceEntity 데이터의 Sort 문제.
  • 2009.12.16 Azure에서 데이터 구성방법(2)
  • 2009.12.15 Azure에서 데이터 구성 방법.

Java의 웹 프로그래밍의 오해 from ASP.NET

기술자료/Web 2009. 12. 26. 15:25

지금까지 해온 웹 프로그래밍은 ASP.NET 2.0 기반으로 해왔기 때문에, 이 지식을 기반으로 Java에 매핑하기 시작했다. 사실 지금까지 ASP.NET 2.0 형태로 Web Form을 구성하면서, 외부에 노출되지 않은 내부 기능들에 많이 답답해 왔던 것도 사실이다.


그런데, 이번 Java기반 웹 프로그래밍을 하면서 이 ASP.NET이 많은 부분에 있어 프로그래머에게 편의를 주고 있다는 점을 알게되었다. ( 물론 Java 기반의 웹 프로그래밍을 전부 파악하고 하는 말은 아니다. 분명 Java에서도 다양한 기능들이 있기 때문에, 쉽게 처리할 수 있는 방법은 있을 것이다. )


일단 ASP.NET 2.0 으로 넘어가면서 웹 페이지 디자인 코드 부분과 코드 부분이 명확하게 나뉘게 되었다. 그래서 실제적인 .NET 코드들은 코드 부분이 담기는 페이지에 담기고, HTML 부분은 ASP 부분에만 담기게 되었다. 그 사이를 IIS와 .NET 엔진에서 알아서 붙여 진행하였다. ( 이 부분은 대부분의 웹 프로그래밍 환경에서는 최악의 문제점으로 알고 있다. 디자인과 코드가 뒤엉키다 보면 유지보수가 너무 어렵다. )


더 결정적인 부분.

사실 Form에서 데이터를 전달할 때, Ghost 페이지라는 것을 만들어 사용했다. 즉, Form에서 입력된 데이터를 DB에 저장하거나, 그 데이터를 기반으로 특정 값을 찾는 작업을 하려고 할 때, 사용자에게 보여주지는 않는 페이지를 Form의 Action으로 등록하여 처리하는 것이다. 


이 때, Servlet과 JSP에서는 이렇게 처리한다.

JSP에는 실제 사용자에게 값을 입력 받을 때 사용되는 Form(혹은 결과값을 보여주는 Form)으로 제공되고, Servlet은 이 Form에서 만들어진 값을 받아 처리하게 되는 일종의 Ghost 페이지처럼 동작하도록 하는 것이다.


즉, 입력 Form(JSP) –> Servlet –> Form(JSP).


합리적이긴 하지만, ASP.NET 2.0 기반 프로그래머 입장에서는 순간 헤매기 십상일 듯 싶었다.

게다가 Servlet 이라는게 사실 Web Server와 직접 연동하여 동작하는 작업을 구성하는 것이기 때문에 왠지 접근하기가 쉽지 않은(.NET 에서는 이 부분의 로직을 모두 숨겨서 알아서 처리해 줬기 때문이다. )부분이라, 망설임이 지대로다.


지금 Google Apps Engine 코드들을 하나씩 까면서 차근 차근 따라가보고 있다.

뭐랄까 새록새록 한 기분?

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[Google Apps Engine] Java SDK 설치하기.

기술자료/Web 2009. 12. 22. 14:32

원본글 : http://code.google.com/appengine/docs/java/gettingstarted/installing.html

Google App Engine에 대한 Java 응용 프로그램은 App Engine Java SDK(Software Development Kit)을 이용하여 만들고, 업로드 하게 됩니다.

SDK에는 직접 제작한 Java 응용 프로그램을 자신의 컴퓨터에서 테스트 해볼 수 있도록

웹 서버 소프트웨어를 포함하고 있습니다.

이 웹 서버에는 모든 형태의 App Engine 서비스를 모의 실험할 수 있도록 준비되어 있습니다.

로컬 버전의 데이터 저장 장소를 제공하며, Google Account 모듈 및 URL 추출 및

Email 발송 등등의 기능들도 포함 되어 있습니다..


Java 구하기.

Google App Engine에서는 Java 5와 Java 6를 지원합니다.

먼저 App Engine을 구동 시키기 위해서는 Java 6의 가상 머신(JVM)과 표준 라이브러리가 팔요합니다.

개인 PC에서 동작되는 내용이 App Engine에서도 정상적으로 동작하기 위해서는

가급적 Java 6에서 컴파일하고, 테스트를 하시는 것을 권장해 드립니다.

하지만, 개발자분들 중에는 Java 6 시용이 쉽지 않은 분들도 계실 것입니다.

( 예를 들면, Mac OS X를 사용하여 개발하시는 분들 같은 경우 최신 버전이 Java 5일 경우가 많습니다.)

일단은 App Engine 자체가 Java 5와의 호환성을 유지하기 때문에,

Java 5로 만들어진 JAR 나 컴파일 된 클래스들도 App Engine에서 정상적으로 동작합니다.


먼저 여러분이 가진 PC 환경에 맞는 Java SE Development Kit(JDK)을 다운로드 받으시고 설치하시기 바랍니다. Mac 사용자 분들은 Apple의 Java 개발자용 사이트 에서 최신 버전의 JDK를 받으시고 설치 하시기 바랍니다.

JDK를 설치하셨다면, 다음 명령을 명령 창(Windows라면 명령줄 프롬프트이고, Mac 사용자라면 Terminal)에 넣어 실행해보시어 현재 설치된 Java 가 정상적으로 설치되어 있는지, 버전이 맞는지 등을 확인해주시기 바랍니다.

java -version

javac -version

만일 Java 6가 설치되어 있다면 출력되는 내용에 버전 번호가 대략 1.6.0 이런 식으로 표시될 것입니다. 만일 Java 5라면, 1.5.0 이런 식으로 출력되겠죠.


Eclipse와 Google Plugin for Eclipse 사용하기.

Eclipse 개발환경을 이용하여 Java를 개발하고 있으시다면,

Google Plugin for Eclipse를 사용하여 개발, 테스트, 배포의 모든 단계가 훨씬 간단하게 하실 수 있습니다. Plugin은 Eclipse 안에서 응용 프로그램의 빌드, 테스트, 배포 전 단계에 필요한 모든 것을

처리할 수 있도록 각종 도구들을 담고 있습니다.

Plugin 자체는 Eclipse에서 제공하는 Software Update 기능을 사용하여 설치할 수 있습니다.

그러나, Eclipse 의 버전에 따라 설치할 수 있는 Plugin이 다릅니다.

다음은 각 버전 별로 설치할 수 있는 Plugin의 URL입니다.


Google Plugin for Eclipse – for Eclipse 3.3 ( Europa )

http://dl.google.com/eclipse/plugin/3.3

Google Plugin for Eclipse – for Eclipse 3.4 ( Ganymede )

http://dl.google.com/eclipse/plugin/3.4

Google Plugin for Eclipse – for Eclipse 3.5 ( Galilieo )

http://dl.google.com/eclipse/plugin/3.5

Eclipse에서 Software Update를 이용하여 Plugin을 설치하는 방법이나,

새로운 프로젝트를 생성하는 방법 등에 대한 자세한 내용은 Google Eclipse Plugin을 사용하기를 보시기 바랍니다.


SDK 구하기.

Eclipse를 이용하여 Google Plugin을 설치하셨다면,

App Engine SDK가 자동적으로 Eclipse 안에 설치됩니다.

(개별적으로 설치하여 직접 콘솔에서 작업하는 경우라면 원본의 내용을 참고하시기 바랍니다.)


데모 응용프로그램 실행해보기

Eclipse의 Plugin 형태로 SDK가 설치되어 있다면, Eclipse 설치 디렉터리 밑에 plugins/com.google.appengine.eclipse.sdkbundle_VERSION/ 의 경로 중

VERSION 부분이 SDK 버전 번호로 구성된 폴더에 위치되어 있습니다.
(예를 들어 1.3.0 버전이라면 plugins/com.google.appengine.eclipse.sdkbundle.1.3.0_1.3.0.v200912141120 식으로 담겨 있습니다.) 일단 명령 창을 띄워서 디렉터리를 저 위치로 이동하시기 바랍니다.

만일 Mac OS X나 Linux 사용자 이면,

실행용 배치 파일이 실행될 수 있도록 실행 권한이 설정되어 있는지 반드시 확인해주시기 바랍니다.

( chmod u+x dev_appserver.sh 라는 명령을 입력하여 설정되어 있어야 합니다. )


윈도우 사용자라면, 다음 명령어를 입력하면 개발용 서버에 방명록 데모 응용 프로그램이 실행되게 됩니다.
(아래 내용의 줄 바꿈은 길이가 너무 길어 줄 바꿈이 된 것입니다. 실제로는 한 줄로 표현 되야 합니다.)

appengine-java-sdk\bin\dev_appserver.cmd appengine-java-sdk
\demos\guestbook\war

Mac OS X 나 Linux 사용자는 다음과 같은 명령어를 입력하시면 됩니다.
(아래 내용의 줄 바꿈은 길이가 너무 길어 줄 바꿈이 된 것입니다. 실제로는 한 줄로 표현 되야 합니다.)

./appengine-java-sdk/bin/dev_appserver.sh appengine-java-sdk
/demos/guestbook/war

개발 서버가 실행되면, 기본 설정이 8080 포트를 이용하여 요청 처리하게 됩니다.
브라우저를 실행하여 다음 URL을 넣어보시기 바랍니다.


http://localhost:8080/


명령 줄에서 개발용 웹 서버 실행에 대한 더 자세한 정보가 필요하시면
the Dev Web Server referece를 참고하시기 바랍니다.

서버를 중지하시려면, 명령 창에서 Ctrl + C를 누르면 됩니다.


다음은…

여러분의 PC에 App Engine 응용 프로그램을 개발하고 테스트 할 수 있는 개발 환경이 갖추어졌을 것입니다.
이제부터 간단한 프로젝트를 시작하도록 하겠습니다.


프로젝트 생성하기로 계속됩니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[Google Apps Engine] 소개

기술자료/Web 2009. 12. 22. 14:02

원본글 : http://code.google.com/appengine/docs/java/gettingstarted/introduction.html


Google Apps Engine에 오신 것을 환영합니다!

App Engine 응용 프로그램 제작은 간단하기 때문에, 몇 분 정도만 투자해도 쉽게 만들 수 있습니다.

그리고 시작하는데 비용이 전혀 들지 않습니다. 단지,

만든 응용 프로그램을 업로드하고, 사용자들과 나누어 활용하시기만 합니다.

이 작업에 대해 아무런 비용 청구는 없습니다.


Google Apps Engine은 Java 또는 Python을 이용하여 제작하실 수 있습니다.

여기에서 소개하는 방법은 Java를 이용한 방법으로 만일 Python으로 제작하시고 싶으시다면,

Getting Start: Python 을 보시기 바랍니다.


이 튜토리얼에서는 다음과 같은 내용들을 알려드릴 것입니다.

  • JSP 와 서블릿과 같은 표준 Java 웹 기술을 사용하여 App Engine 응용 프로그램 만드는 법.
  • Eclipse로 App Engine Java 프로젝트를 생성하는 방법
    (원본에서는 없이 하는 방법도 소개하나, 여기서는 생략)
  • Google Plugin for Eclipse 를 이용하여 App Engine 개발하기
  • Java Data Object(JDO) 표준 인터페이스를 활용한 App Engine 저장 방법 사용하기.
  • 사용자 인증하는 방법을 Google Account를 이용하여 App Engine 응용 프로그램에서 처리하기.
  • App Engine으로 새로 만든 응용 프로그램을 업로드 하기.

튜토리얼 끝 즈음에서 여러분들은 공용 게시판에 메시지를 쓸 수 있는

단순한 방명록 응용 프로그램을 직접 작성해보게 됩니다.

다음은.

Google App Engine 자바 응용 프로그램을 개발하기 위해서는 먼저 App Engine Java SDK(software development kit)과 그 외 관련 구성요소들을 다운로드 받으셔야 합니다.

2009/12/22 14:02Java SDK 설치하기로 계속 됩니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

Lotto 당첨번호 및 기타 정보 저장 서비스 제공 - Azure 버전

기술자료/Web 2009. 12. 21. 18:19

Windows Azure 학습할 겸 해서 만들어봤다.

Hands on Lab에 들어있는 내용을 그대로 만들기는 성격 상 허락되지 않기 때문에,
나름대로 쓸모가 있을 법한 내용을 기반으로 구성해보았다.

원리는 간단하다. 현재 로또 사이트를 접속해서 사이트에서 제공하는 당첨번호를 강제로 긁어와
내부적으로 데이터를 쌓는다. 쌓을 때, 번호 별 출현 갯수나, 합계 별 출현 갯수등을 제공하는 UI를 제공한다.
원래는 당첨 번호 확인 같은 기능이나, 자신의 번호 저장 기능 같은 것도 만들어 넣으려고 계획했지만,
Azure가 유료 서비스가 될 거라는 이야기에, 그냥 포기했다.

차라리 무료로 접근이 가능한 Google Apps Engine 쪽으로 선회할 예정이다.

그래도 일단 만들어 본 내용이기 때문에, 소스를 남기도록 한다.

소스 다운로드 링크 : 클릭

Codeplex에 올려 놓으려고 했지만, VS 2008 Team Explorer 클라이언트를 깔기
귀찮아서, 걍 포기.

이 코드를 실행하려면, 최소한 자신의 PC 안에 Azure 개발 플랫폼을 구축해야 한다.

  • Windows vista 이상.
  • IIS 7.0 이상.
  • Visual Studio 2008 이상.
  • SQL Express 2008 이상.
  • Azure SDK 설치.

자세한 내용은 이전 포스트를 참고 하면 된다.

일단 이 버전으로 이번 App는 Close.

이제 부터 Google Apps Engine으로 Go! 다. Java로 Go! 다!!!!


UPDATE !!! 파일 내용에 대한 링크를 Skydrive를 이용해서 올려놨었는데, 이상하게 링크가 깨지더군요.
그래서 개인적으로 사용중인 NAS 쪽에 올려놨습니다.

뭐 필요하신분은 그다지 없을 것 같지만, 그래도 혹시나 하는 마음에 변경 처리했습니다.
728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

CloudQueueClient.GetQueueReference 의 인자값 문제.

기술자료/Web 2009. 12. 18. 10:09
아직 문서들을 정독하지 않아서, 몰랐다.

public CloudQueue GetQueueReference ( string queueAddress )

를 보면 queueAddress 라는 인자값을 넣게 되어 있다.

여기에 늘 그렇듯 낙타식 문자열(카멜식 이름. 예를 들면.. guestBookQueue )으로 적어 주었는데,
에러가 난다. 그래서 한참을 헤맸는데, Hands on Lab을 보니, 모든게 소문자...
혹시나 해서 소문자로 모두 변경해서 써보니, 직빵으로 해결되었다는...

이 주소값은 기본값이 소문자로 되어 있으며 소문자 외의 문자가 오면,
역시나 알기 힘든 Exception을 뱉는거 같다.

이야... 이거 난이도가 높다.




728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

TableServiceEntity 데이터의 Sort 문제.

기술자료/Web 2009. 12. 17. 11:05
이전 포스트에서 특정 데이터의 Query를 할 때 LINQ에서 제공하는 select 문자을 이용하여 아래와 같이 처리한 적이 있다.
var result = from g in this.context.AnalysisSumDataEntry
                       where g.PartitionKey == "AnalysisSumData"
                         select g;

그런데 일반적인 LINQ 방법으로 저 내용을 Sort를 하려면 아래와 같이 되는 줄 알았다.

var result = from g in this.context.AnalysisSumDataEntry
                       where g.PartitionKey == "AnalysisSumData"
                       orderby g.Count                       
                       select g;

굵게 해서 표시한 저 orderby를 사용하고, 실제 Sort 할 필드에 대해서 정의한 내용을 넣으려 했다.
( 참고로 AnalysisSumDataEntry 에는 Count와 Index 라는 int 형 프로퍼티를 가지고 있다. )

그런데, 위와 같이 처리하려고만 하면, 결과 값에 Exception 이 담겨 있어, toList 부터 ElementAt 까지 뭐든 메소드든 다 Exception을 뿜어버리고 만다. 즉 결과에 오류가 있다는 것이다.
혹시나 하는 마음에 orderby를 지우자 정상적으로 동작한다.
분명 숫자를 의미하는 int 형일텐데.... 라는 생각에 이런 저런 고민을 무럭 무럭 자랐다.

그래서 결국 편법을 택했고 그 방법은 아래와 같다.       
private IEnumerable<AnalysisSumDataEntry> SelectBase()
        {
            var result = from g in this.context.AnalysisSumDataEntry
                         where g.PartitionKey == "AnalysisSumData"
                         select g;
           
            return result;
        }

        public List<AnalysisSumDataEntry> Select()
        {
            IEnumerable<AnalysisSumDataEntry> result = SelectBase();
            List<AnalysisSumDataEntry> list = result.ToList<AnalysisSumDataEntry>();

            list.Sort(delegate(AnalysisSumDataEntry src, AnalysisSumDataEntry tgt)
            {
                return src.Count - tgt.Count;

            });

            return list;
        }

즉 Generic 에서 제공하는 List 템플릿에 때려 박고, 그 내용을 가지고 List의 Sort를 사용하여 Sort 해버렸다.
지금 방식대로 하면 Desending 즉 내림 차순이 되고 Asending 즉 오름 차순으로 하려면, 굵게 해 놓은 return 값의 식을 역순으로 바꾸면 된다. ( return tgt.Count - src.Count )

이게 답인지는 모르겠지만.. 현재로는 저렇게 밖에는....
아무래도 데이터 선언 방법 부터 차근 차근 LINQ를 따라가봐야 겠다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

Azure에서 데이터 구성방법(2)

기술자료/Web 2009. 12. 16. 11:30

( 어제 다 쓰려고 했는데, c2.net 번역 게시물들을 읽다가 시간이 Over되는 바람에 다 적지 못했습니다. )

4. 데이터 접근용 Class (계속)

앞의 Post에서 실제적인 데이터 접근용 클래스의 틀을 만든 거라면, 지금 부터는 그 안에서 실제적인 동작과, 그 활용 방법을 구현하는 작업을 한다.

a. Select

가장 기초적인 구현입니다. 저장된 데이터가 있어야 겠지만, 대부분의 DB 관련 프로그래밍을 하면, 이 Select 에서 시작해서 Select로 끝나는게 대부분이라 생각한다.
앞의 내용까지 따라갔다면, GuestBookDataSource 라는 이 클래스가 있을 것이고, 그 클래스 안에 아래와 같은 Method를 추가한다.

public IEnumerable<GuestBookDataEntry> Select()
{
    var result = from g in this.context.GuestBookDataEntry
                 where g.PartitionKey == "GuestBookRawData"
                 select g;
    return result;
}

이 내용은 그 Hands on Lab의 내용을 그대로 차용한 것이다.
사실 이 문구를 보고서 심각하게 LINQ 부터 시작해야 할 까? 고민을 많이 했다. 아니 C# 안에서 form, select, where를 쓰는 건 이거 솔직히 반칙이다. MS의 수석 엔진니어들에게 욕이라도 퍼붑고 싶어졌다. 그러나 이미 구현되어 있고, 알게 모르게 .NET 개발자들은 이를 새로운 기술로 받아들여 사용 중이니, 불만은 내 속에서만 삭히고 결국 문법을 가만히 보게 되었다.

먼저 Return Value.

아마 DataTable 이라는 개체를 통해 Select 명령어를 쓰신 분은 약간 부담이 없을듯 싶다.
DataTable.Select()의 결과는 DataRow의 배열 값인데, 저 IEnumerable<GuestBookDataEntry> 라는 것은, GuestBookDataEntry의 배열과 같은 형태라 보면 된다. 단지, 배열보다 더 많은 기능과 활용도가 있다는게 그 차이. 그냥 배열 형태를 좀 멋지게 그리고 유연하게 Return 하는 구나 하고 넘어가면 된다.

자, 이제 부터 진정한 산맥.

var.

무슨 JavaScript도 아니고 var 라니. 그러나 이것도 엄연한 C#의 Keyword. 즉 외부에서 온 값 중 그 형태를 정의할 수 없는 기묘한 값인 경우 이 var를 사용한다. 물론 단항이면 object 한방이면 모든 데이터형 감쌀 수 있지만, 저게 배열일지, 단항일지는 모른다. 그래서 var를 사용한다. var 형태로 정의된 변수는 그 데이터가 처음 들어가는 순간 그 형이 결정된다.

  • var strVal = “aaaa”;     // strVal은 이 순간 문자열로써 동작해버린다.
  • var intVal = 55; // intVal은 이 순간 int (정수형)으로써 동작해 버린다.
  • var dblVal = 5.555; // dblVal은 이 순간 dobule 로써 동작해 버린다.

참… 알기 쉬운 내용이지만, 순간 쓰긴 참 뭐시기한 내용이다. 그래서 var는 초기화 자체를 할 때 아주 고민 지대로다.  그래서 위와 같은 메소드를 만들때, 그냥 var result = …; 라고 적어버렸다.

다음은 from .. ..

앞서 만든 클래스 내용 중 GuestBookContext 라는 것이 있다. 그 안에 아무 생각없이 만든 프로퍼티인 GuestBookDataEntry 라는게 있다. 아마 Return 값이 IQueryable<GuestBookDataEntry> 인데, 바로 이 프로퍼티를 통해서 마치 DB의 Table 처럼 쿼리 할 수 있는 것이다. 아마 내부적으로는 Select … from .. 의 from 처럼 DB 테이블에서 값을 긁어오기 위한 무언가의 작업을 수행하는 것이다.
여튼 이 from 뒤에 쓰일 수 있는 것인 TableServiceContext를 상속받은 클래스에서 IQueryable<T>의 Return 값을 돌려주는 프로퍼티를 써야 된다는 사실만 기억하면 된다.
아 여기서 Table의 문법은 다음과 같다.

<변수명> in <context>.<Property>

즉 아래와 같이 볼 수 있다.

g in this.context.LottoSvcDataEntry

그리고 where .. ..

뭐  from 나올때 이미 감 다 잡으셨지만, 맞다. select form where 이다. 단지 그 순서가 미묘하게 다를 뿐.
SQL의 where 절 쓰듯이 쓰면 된다. 단지 비교 연산자가 C#에서 사용되는 비교 연산자의 차이일 뿐이다.
즉 = –> == 로 AND는 && 로 쓰면 된다.

마지막으로 select

select 뒤에 필드명 적게 되어 있는데, 이 필드를 무작정 적는게 아니고, 앞서 Table 선언할 때 사용한 변수를 이용하여 사용한다. 즉 from <변수명> in <IQueryable 프로퍼티> 의 형태에서 있는 <변수명> 이거다.
위의 예제에서는 g 라는 변수를 썼으니 여기서는 g 라고 썼다. 만을 그냥 그 변수명을 쓰면 “*”의 의미가 된다.

아직 실험은 안해봤지만, 특정 필드의 값을 빼려면, <변수명>.<필드명> 하면 될 거라 생각된다. 즉 이름 빼오기 할 때, g.Name 하면 되지 않을까 싶다.나중에 한번 해보려고 한다.

여튼 이와 같이 select 문을 만들어 var의 변수에 때려 박으면 IEnumerable<T> 형태로 값이 돌아간다.
값이 있든 없던 위의 형태로 들어가게 된다.

b.Insert

사실 이 부분 부터 해야 select 테스트도 되지만, 사실 SQL의 핵은 Select 다 보니, Select를 먼저 설명하게 되었다. 애석하게도(?) Insert는 위의 형태 처럼 C# 같지도 않은 문법으로 처리하지 않는다. 즉 아주 평범하게 (?) Insert를 한다.

먼저 Insert 할 데이터 기본형인 Entitiy 클래스를 new 해서 만든다. 그리고 그 데이터에 값을 넣고, AddObject를 통해 값을 밀어 넣는다. 마지막으로 Save 한다. 이게 전부다.

즉 위의 예제로 본다면 아래와 같다.

public void AddDataEntry(string Name, string Email, string HomePageUrl)
{
    GuestBookDataEntry newItem = new GuestBookDataEntry ();

    newItem.Name = Name;
    newItem.Email = Email;
    newItem.HomePage = HomePageUrl;
    newItem.writtenDate = DateTime.Now;

    this.context.AddObject("GuestBookDataEntry ", newItem);
    this.context.SaveChanges();
}

즉 newItem 이라는 변수에 새로운 데이터를 넣을 공간을 만들고, 그 안에 데이터를 채우고 난 뒤, AddObject 함수를 통해 값을 밀어 넣는다. 이 때, AddObject 라는 함수 첫번째 인자가 문자열을 넣게 되어 있는데, 이 부분에 Entity에 해당하는 클래스 이름을 넣는다. 즉 위에서는 GuestBookDataEntry 이니, 이를 넣으면 된다.
(내부적으로 어셈블리에 대한 reflect 작업을 할 때 사용되는 것 같다. 만일 저 문자열이 틀리면 알아 먹기 힘든 오류가 나기 때문에 주의해서 넣도록 한다. )
자 일단 변경작업을 수행했으니, 마지막으로 SaveChanges 함수를 불러 저장하도록 한다.

c.Update

이것 역시 Insert와 유사하다. 해당하는 Entity의 개체를 꺼내고 그 개체의 내용을 변경한 뒤, 변경용 메소드인 UpdateObject 를 호출하고, 마지막으로 SaveChange 한번 해주면 된다.
뭐 역시 이 또한 코드로 보는게 제일 빠를 듯.

public void ChangeHomePageUrl(string Name, string HomePageUrl)
{
    var result = from g in this.context.GuestBookDataEntry
        where g.PartitionKey == "GuestBookRawData" && g.Name == Name
        select g;

    if(result.Count<GuestBookRawData>() == 1)
    {
        GuestBookDataEntry curEntry = result.ElementAt<GuestBookRawData>(0);
        curEntry.HomePage = HomePageUrl;
        this.context.UpdateObject(curEntry);
        this.context.SaveChanges();
    }
}

보면 특정 Entity의 값을 가져와서 그 값을 변경한 뒤, UpdateObject를 부르고 다시 SaveChange 하는 것을 볼 수 있다. (굵게 칠해진 부분만 참조)

기존 값을 불러오는데는 앞서 사용한 select를 사용했다. 단, 조건이 하나 더 붙는데, Name이 같은 이름을 가진 Name 인경우에 해당하는 것이다. ( 물론 Name이 둘 이상이면 처리하지 않는 문제점은 그대로 안고 가지만… ) 일단, 무조건 이름이 1개라는 가정에서 해당하는 이름이 적은 내용을 가져온 뒤, 최종적으로 꺼내와서 그 안의 값을 변경했다. 여기서는 HomePage가 그 값을 의미한다.
그리고 나서 UpdateObject를 호출한다. AddObject와는 다르게 이미 존재하는 Entity이기 때문에, 굳이 클래스명 따위는 넘길 필요가 없을 것이다. 업데이트가 완료되면 마지막으로 Save를 하는 작업을 하게 된다.

d.Delete

이제 Action의 마지막 Delete 이다. Update와 모든 동작이 동일하며, 단지, UpdateObject를 쓰는게 아니라, DeleteObject를 쓰면 된다. 특정 이름의 항목을 지우는 로직이다.

public void DeleteBook(string Name)
{
    var result = from g in this.context.GuestBookDataEntry
        where g.PartitionKey == "GuestBookRawData" && g.Name == Name
        select g;

   if(result.Count<GuestBookRawData>() > 0)
  {   
     foreach(GuestBookDataEntity entry in result)
    {
        this.context.DeleteObject(curEntry);
     }
     this.context.SaveChanges();
   }
}

Select로 각 Entity 들을 빼내고 그 내용을 DeleteObject를 호출 한 뒤, 맨 마지막에 SaveChanges()를 호출한다.

 

5. 데이터 활용.

자 이제 만들어진 DataSource를 가지고 데이터 조작을 해보도록 한다.
사용자와 직접적인 I/F를 담당하는 것은 Web_Role 부분. 기본적인 Web-Role을 만들었다면, 별도 Web Project가 한개 열렸을 것이다. 이 Web-Role용 프로젝트에서 참조를 하나 추가한다. 추가할 참조는 바로 이 DataSource가 담긴 프로젝트. 일단 참조 관계가 만들어져야 Web-Role에서 사용 가능하다.

먼저 기본적으로 생성된 Default.aspx 의 코드에서 Select를 호출해서 사용해 본다.
DataSource로도 바로 이용가능하기 때문에, Hands on Lab을 보면, DataGrid를 이용하여 한 큐에 작성한 결과물을 보여준다. 이 방법도 좋지만, 좀 무식하게 만들어 봐야 실제로 데이터를 꺼내고 하는게 눈에 보일 것 같다.

먼저 TextBox를 Web-Form에 추가한다.
그리고 난뒤 그 TextBox의 이름은 txtResult로 한다. 또, TextMode를 MultiLine으로 하고 Rows를 10 정도로 하자. 그러면 TextArea가 되니까, 결과물 보기에 그냥이다.
이제 다음과 같은 코드를 Page_Load 메소드 안에 추가한다.

GuestBookDataSource ds = new GuestBookDataSource();
IEnumerable<GuestBookDataEntry> result = ds.Select();
System.Text.StringBuilder sbResult = new System.Text.StringBuilder();
foreach (GuestBookDataEntry entry in result)
{
    sbResult.Append(entry.Name);
    sbResult.Append("(");
    sbResult.Append(entry.Email);
    sbResult.Append(" / ");
    sbResult.Append(entry.HomePage);
    sbResult.Append(")");
    sbResult.Append(entry.writtenDate.ToString());
    sbResult.AppendLine();
}
txtResult.Text = sbResult.ToString();

데이터를 꺼내는 방법이 보이지 않는가? 그냥 GuestBookDataSource를 생성하고, 그 결과 값을 이용하여 메소드를 호출하기만 하면 된다. 그리고 그 결과값을 나열하면 된다.
Insert나, Delete, Update도 마찬가지로 GuestBookDataSource를 생성한 뒤 불러 주면 된다.

6. 정리.

데이터 처리 관련해서 올려서 정리해봤다. 사실 LINQ에 대한 기본 지식이 거의 전무하기 때문에, 이 내용에 대해 정확한 동작 방법이나, 올바른 방법이나, 효율적인 처리에 대해서는 거의 알지 못한다.
단지, Hands on Lab을 따라하다가 보니, 이렇게 짜는 구나 정도이다.

필자 처럼 구현에 성급하신 분은 한번 위의 방법대로 구현해 보면 될 것이다.

( 현재 Lotto 당첨 번호 관련된 서비스를 한번 만들고 있다. 별로 로직은 어렵지 않은데, 은근히 Azure 자체의 벽이 높아서 당황했다. 그 중간의 결과를 여기에 기록으로 남기고 있다. )

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

Azure에서 데이터 구성 방법.

기술자료/Web 2009. 12. 15. 16:27

( 조심 : 이 정보는 직접 Coding을 해서 얻은 결과 입니다. 실제 Azure 아키텍처를 명확히 이해하여 쓴 글은 아닙니다. )

Windows Azure에서 데이터를 저장하는 방식은 Table 기반의 저장 방식을 따른다.
물론 Azure 서비스 중 하나인 SQL 서비스를 직접 이용하는 방법이 있지만,
사실 그 방법 말고도, .NET 3.5 에서 제공하는 LINQ 방식을 이용하여 만드는 방법이 있다.
그리고 현재 Windows Azure Platform Kit ( 11월 버전 ) 에 담긴 Hands on Lab을 하다 보면,
이렇게 구성하는 구나, 싶다.


1. 데이터 저장을 위한 Table 구성

데이터의 기본은 표. 즉 Table 이다. 그리고 그 Table에 데이터를 쌓는 것을 레코드 혹은 Row 라고 한다.
그리고 각 데이터의 종류를 나타내는 것을 필드 혹은 Column 이라고 한다.

Table

  Column  
Row ->    
     
     

여기서는 위의 구조 중 Row와 Table을 구현하여 데이터를 구성하게 된다.

먼저 Table을 역할을 하는 Data 기본 셋으로 Windows Class Library 프로젝트를 하나 생성한다.
즉 Table이 여러 개 필요하면 그에 맞추어 프로젝트를 생성하면 된다.
( 이 부분은 나중에 Azure 문서 중 Data 관련된 사항을 더 공부하고 정리할 예정이다.)

즉 필요한 Table 만큼의 Windows Class Library 프로젝트를 생성하도록 한다.( Hands on Lab에서는 방명록을 구현하는데 그 때 사용되는 데이터를 구성하기 위해 하나의 Class Library 프로젝트를 만드는데 바로 그게 데이터 저장을 위한 Table 역할을 하게 된다. )

– 단 .NET Framework 3.5 이상 용으로 만들어야 한다.
    그래서 개발 환경 조건에, Visual Studio 2008 이상이 필요한 것이다.


이 때 프로젝트에는 다음과 같은 어셈블리를 Reference 해야 한다.

System.Data.Services.Client   ( .NET Framework 3.5 )
Microsoft.WindowsAzure.StorageClient   ( Azure SDK )

일단 위의 레퍼런스가 끝났다면 이제 Row을 구성한다.

2. 데이터 구조 잡기 가장 기초 부분 Entity

위에서 언급한 Row 부분 – 관점을 조금 돌리면 Column을 구성하는 것? 이라고 볼 수도 있다. - 을 구성하는 방법이다. 어떤 데이터를 어떻게 저장할 것인지를 결정하는 부분이다.
방법은 다음과 같다.

  1. public 클래스를 만든다.
  2. Microsoft.WindowsAzure.StorageClient.TableServiceEntity 를 상속 받는다.
  3. 생성자를 만든다.
  4. 생성자 안에 PartitionKey 와 Row Key를 설정한다.
  5. 프로퍼티를 만든다.

위의 다섯 단계를 찬찬히 설명하면 아래와 같다.

1과 2는 C#의 기초 단계와 다름이 없을 것이다.
일단 using을 써서 Microsoft.WindowsAzure.StorageClient 를 추가하는 줄을 넣는다.

using System;
using Microsoft.WindowsAzure.StorageClient;

그리고 난 뒤에, class 앞에 public 넣고, 맨 뒤에 : 을 넣은 뒤, TableServiceEntitiy를 넣는다

using System;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataEntry : TableServiceEntity
    {

    }

}

위의 단계까지 왔으면 일단 기본은 끝난 것이다.

3~4 번 단계에서는 생성자를 생성하고, 그 안에 고유의 값을 넣는 작업을 한다.
단 기본 생성자로 생성해준다. 그리고, 이 GuestBookDataEntry 클래스는 프로젝트 밖에서  new 해야 되기 때문에, 이 생성자를 반드시 public으로 선언해야 한다. 
생성자 안에서  PartitionKey와 RowKey에 고유의 값을 넣어주도록 한다.
RowKey는 모든 데이터에서도 가장 유일한 값이여야 한다는 것은 이해했지만, PartitionKey는 DB의 Partition 과 유사한 기능 같았다. 그래서 이 부분은 그냥 다른 Table과 구분되는 정도의 레벨의 데이터로 생각하여 넣었다. PartitionKey 는 알아서.. 잘 넣어주시면 될 것 같다.

using System;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataEntry : TableServiceEntity
    {
        public GuestBookDataEntry()
        {
            PartitionKey = "GuestBookRawData";

            RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
        }
    }
}


5번 단계에서는 실제 값이 어떻게 들어갈지를 정의하면 된다.

using System;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataEntry : TableServiceEntity
    { 
       public String Name { get; set; }
        public String Email { get; set; }
        public String HomePage { get; set; }
        public DateTime writtenDate { get; set; }

        public GuestBookDataEntry()
        {
            PartitionKey = "GuestBookRawData";

            RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
        }
    }
}

C# 3.0 에서 사용되는 프로퍼티의 기본형으로 써주면 된다.
public으로 정의하고 그 데이터 형을 결정한 뒤, get과 set을 정의해주면 된다.
( C# 3.0에서 보면, 프로퍼티에서 그냥 get;set; 을 써주면 알아서 저장된다. )

아직은 기본형만 써봐서, 다른 형태의 Class 데이터나 복합형 데이터는 만들어보지는 않았다.
일단, 위와 같은 형태로 구성한다.

그러면 기본적인 Row 가 정의된다.

3. Context 구성하기.

데이터의 입출력을 할 때, 그 흐름을 정의하는 부분이라고 보면 된다.
어디서 저장되고, 어디로 저장되며 어떻게 진행되는지. 그러나, 실제로의 구현은 모두 기본값 만을 이용하여 생성할 예정이다. 그러므로 코드는 무척 간단하다.

using System;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataContext : TableServiceContext
    {
        public GuestBookDataContext(string baseAddress, StorageCredentials credentions)
            : base(baseAddress, credentions)
        {
        }

        public IQueryable<GuestBookDataEntry> GuestBookDataEntry
        {
            get
            {
                return this.CreateQuery<GuestBookDataEntry>("GuestBookDataEntry");
            }
        }
    }
}

위의 코드 중 굵은 부분만 구성해주면 된다. 그런데, 저 붉은 부분은 좀 신경써서 정리해주어야 한다.
만일 저 붉은 내용의 문자열이 조금이라도 틀리면 알기 힘든 오류를 내어 디버깅 자체가 어려워 질 수 있다.
반드시 저 붉은색 부분은 신경써서 넣어주기 바란다. 저 붉은 부분에 넣는 것은 앞서 선언한 Entity 에 대한 Class 이름이다.

4. 데이터 접근용 Class.

사실 위의 두개의 class만 있어도 기본적인 데이터 접근은 가능하다. 하지만, 외부에서 데이터 호출을 위한 로직을 직접 선언하여 구축하는건 조금 지저분 해지기 때문에, 가급적 이런 대리자의 역할을 하는 클래스 구성이 효율적일 수 있다.

이 클래스는 굳이 상속 받을 필요는 없다. 생성 한 뒤, 데이터를 쿼리하거나 데이터를 넣는 정도의 인터페이스만 제공하면 되는 클래스 이기 때문이다.

먼저 Skelton 코드로는 다음과 같다.

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataSource
    {
        private static CloudStorageAccount storageAccount;
        private LottoSvcDataContext context;

        static GuestBookDataSource()
        {
            storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

            CloudTableClient.CreateTablesFromModel(
                typeof(GuestBookDataContext),
                storageAccount.TableEndpoint.AbsoluteUri,
                storageAccount.Credentials);
        }

        public GuestBookDataSource()
        {
            this.context = new GuestBookDataContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
            this.context.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
        }

    }
}

위에서 보는 것과 같이 생성자를 두 개 만든다.

둘 다 생성자이기는 하지만 그 역할을 판이하게 다르다. static 으로 선언한 생성자는 프로그램이 시작할 때 new 하던지 말던지 1회성으로 무조건 1번 실행하는 단발성 생성자다. 여기서는 앞서 만든 테이블 구조에 따라 가상의 테이블을 만들어주는 역할을 하게 된다.

그리고 두번째에 위치한 생성자는 일반적인 생성자로, 실제 이 데이터 관련 작업을 수행할 때 new 해서 생성하면 불리는 생성자다.

그리서 첫번째의 static 생성자에서는 CloudStorage 관련 도구를 사용하여 Table을 실제적인 인스턴스를 생성하는데 그 역할을 다하며, 두번재의 일반 생성자에서는 그 만들어진 Table에 접속하기 위한 기초적인 내용이 담기게 된다. 이 때, Static 생성자에서 사용하는 DataConnectionString 부분을 주목하자.
저 문자열이 뜬금없이 나온 문자열은 아니다. 분명 누군가가 저 값을 가져왔기에 그 내용을 쓸 수 있는 것이다.

저 내용은 이 DataSource를 New 해서 만들어서 사용하는 주체인 Web-Role 혹은 Worker-Role의 옵션에서 설정하게 된다. 이에 대한 설명은 나중에, 그냥 설정하는 방법은 다음과 같다.

  1. Solution Explorer 안에서 Service 목록이 나오는 곳을 찾는다. ( Azure 프로젝트로 만듦면 특이한 아이콘으로 생긴 프로젝트가 보인다 )
  2. 그 중에 설정하려고 하는 Role 부분에서 오른쪽 버튼을 클릭한다.
  3. 속성 창이 뜨면, 왼쪽 항목 Tab에서 Settings를 선택하고 AddString을 한 뒤, Name에 DataConnectionString을 넣고, Type은 ConnectionString을 Value는 그냥 기본값을 둔다. ( 기본값으로 하면, 로컬 DB에 저장하겠다는 의미 )

일단 이 DataSource 라는 것을 사용하는게 Web-Role이라는 가정하예서, Web-Role에 있는 설정을 변경하는 작업을 나타낸다.

일단 여기까지.
실제 DataSource 의 Select, Insert, Update, Delete 구현은 다음으로~

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

  • «
  • 1
  • ···
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • ···
  • 44
  • »
250x250

블로그 내에 소스 코드 삽입 이사온 기념 스킨도... RSS 전문 기능 비활성화 관련. 스킨 바꾸어 보았습니다. 서버 파일 정리 좀 했습니다.

«   2025/05   »
일 월 화 수 목 금 토
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

것 블로그 수 e-book Google Apps Engine 개발환경 2010 오류 me2dayzm 좀 지름신 불만 Tutorial WSS SharePoint me2photo java windows me2sms moss 매뉴얼 친구 twi2me Visual Studio Azure MOSS 2007 협업 Buscuit 인터파크 비스킷

  • Total :
  • Today :
  • Yesterday :

Copyright © 2015-2025 Socialdev. All Rights Reserved.

Copyright © 2015-2025 Socialdev. All Rights Reserved.

티스토리툴바