2009-11-27

니콘 카메라


예전에 D300 을 구입해서 사용하다가 기변을 했었습니다. D300 의 색감과 무게 때문이었지요. 처음 사용한 기종이 Samsung GX-1S 였는데, 색감은 그런데로 괜찮았거든요. 그런데 D300은 아무리 픽쳐콘트롤을 변경하여도 전혀 마음에 들지 않는 색만 보여주었습니다. 그러다가, 올림푸스도 사용해보고, 다시 팬탁스 K100D를 사용하고 있지요.


오늘 어쩌다가 SLRCLUB 의 니콘 포럼을 들어가서 사진들을 보았는데, 이상하게도 대부분 사진들이 괜찮게 나오더군요. JPG로 리사이즈만 한 사진들이 전혀 색감이 이상하지 않고 잘 나오더라는 것입니다. 보통 D300을 야생마 같은 카메라라고 표현합니다. 처음에는 힘들지만 기기에 적응이 되면 더욱 좋은 사진을 뽑을 수 있다는 거죠. 더군다나, 입문기인 D3000 의 경우는 Auto화밸로도 괜찮은 색감을 보여주고 있습니다. 완전히 예상 밖이었습니다. 결국, 제가 노력이 부족해서 D300을 제것으로 만들지 못한 것이었습니다.

이 참에 다시 니콘으로 도전을 해볼까 생각중입니다. 기종은 D90. 저에게는 최적의 크기와 무게를 가지고 있습니다. 기능 또한 타사의 왠만한 중급기에 필적하지요. 원래는 내년 1월쯤에 캐논 50D를 구입하려고 마음 먹고 있었습니다. 이제 다시 50D 대신 D90을 구입하려고 합니다. 그런데, 요즘 피아노를 배우기 시작해서 디지털피아노를 구입해야 해서, D90은 약간 미루어서 4월쯤에나 생각해야겠어요. ^^; 어쩌면 그냥 확 지를지도 모릅니다.

2009-11-23

성인을 위한 피아노 어드벤쳐



결국 피아노 레슨까지 받기로 했습니다. 이렇게 되면, 피아노도 한대 구입해야겠네요. 그리고, 지난번에 바이엘 교본은 당분간 미루어두어야 겠어요. 레슨 선생님이 진행하는 교재가 "성인을 위한 피아노 어디벤처"이기 때문이지요. 잠깐 서점에서 봤을때 구성이 꽤 괜찮았던 것 같아요. 오늘 아침에 주문해서 저녁에 수영 다녀오니 도착해 있네요. 여기에 "나의 첫번째 스케일북"을 동시에 진행한다고 합니다. 이 책은 손가락 기술을 연마하는데 집중한다고 합니다. 이번주 토요일에 첫 레슨이 있는데 무척이나 기대됩니다. 레슨 선생님이 무척 이쁘고 얘기도 잘 통해서 잘 배울 수 있을 것 같네요. *^^*

2009-11-17

바이엘 피아노 교본 (BEYER, VORSCHULE IM KLAVIERSPIEL Op. 101)




저에게 이런 날도 오게 되는군요. 악기를 하나 정해서 연주하고 싶은데 어떤 악기가 좋을까 고민을 많이 했습니다. 그런데, 음악에 대한 지식과 경험은 너무나도 빈약합니다. 처음에는 플룻, 오카리나, 클라리넷 등을 고민해보았습니다. 플룻은 소리를 내는 것부터 고통이더군요. 오카리나는 왠지 멋이 없구요. 클라리넷은 괜찮긴 할 것 같지만 왠지 다가가기가 쉽지 않았습니다. 아무것도 모르는 상태인 저에게는 가장 기본이 되는 악기가 필요했습니다. 결국에는 리코더까지도 생각해내었지요. 관악기의 경우 운지법이 존재하고 각 음역의 소리를 내려면 한정된 구멍을 다양한 조합으로 소리를 내야 했습니다. 음악을 도무지 이해할 수 없는 저에게는 어려운 일이었지요.

그렇다면 그런 조합이 없이 모든 음을 낼 수 있는 악기가 무엇인가 생각해보니, 피아노였습니다. 단지 피아노는 규모가 있기에 휴대하기는 어려워서 아예 생각을 하지 못했던 것이지요. 그리고 악기 연습을 할때 소리로 인해서 주변 사람들에게 피해를 줄 수 있었는데, 피아노는 디지털로 마련한다면 헤드셋으로 혼자서만 들으며 연습할 수 있는 장점도 있습니다. 이런 이유로 피아노를 배우기로 했습니다. 일단 지인으로부터 야마하 전자키보드를 빌리기로 했습니다. 디지털피아노보다는 건반수도 적고 건반을 누르는 감도 그다지 좋지 않지만, 취미로 배우는 저로서는 충분히 좋은 물건입니다.

이제 피아노도 마련이 되었으니, 어떤 과정을 통해서 배우느냐가 관건인데, 일반적인 과정을 살펴보니, 바이엘 → 체르니100 → 체르니30 → 체르니40 등의 순서로 배운다고 합니다. 바이엘이 가장 기초적인 과정이고 체르니는 기본적인 테크닉을 연습하는 과정이라고 합니다. 그렇다면 바이엘을 배우는 것이 첫번째라고 하니 교재가 필요하겠지요. 서점에 가서 보니 아주 다양한 바이엘 책들이 있었는데, 다들 어린이를 위해서 큼직 큼직하게 새로 편찬한 것들이더라구요. 그런 것들 보다는 원문에 충실하게 되어 있는 책이 없을까 찾아보니 위에 있는 책이 바로 그것이었습니다. 아무래도 원문으로 되어 있는 것이 레슨을 받을때에도 참고하기 좋을듯 해서 말이지요. 책의 내용이야 여러세월동안 검증된 것이니 고민할 필요가 없지요. 책 가격도 오프라인에서 4,000원으로 저렴하게 구입했습니다.

레슨은 동영상 강의를 통해서 독학을 하려고 합니다. 바이엘을 마치고 체르니를 진행할때에는 선생님을 통해서 레슨을 받는 것도 괜찮을것 같고요. 멋진 연주를 할 수 있을때까지 즐겁게 배우고 싶습니다. *^^* 혹시 조언을 해주실 분이 있다면 더 좋겠네요~

2009-11-16

세상을 가지고 노는 힘, 유머력



요즘 경제도 좋지않고 사회도 많이 어두워지고 있는 것 같습니다. 좌절하는 사람들도 많고 화를 내는 사람들도 많아졌어요. 저 또한 이런 저런 일들로 인해서 표정이 어두워지는 느낌이 듭니다. 이럴때일수록 즐거운 마음을 가지고 생활하는 것이 필요할 거에요. 항상 즐겁고 행복한 생각들로 가득찬 생각을 하면서 말이죠. 매일 유머 하나씩 생각해서 사람들에게 이야기해주기를 실천해보면 어떨까요? 이런 점에 이 책이 무척 마음에 듭니다. 특히 책 지은이(최규상) 사이트를 운영하면서 메일링도 보내주고 있습니다. 이 메일들이라도 보면서 다른 분들도 즐거운 마음을 가지길 빕니다.

2009-11-12

Tomcat 6 + Struts 2 + iBATIS 2 + PostgreSQL 8.3 설정하기

WindowsXP 환경에서 설치하는 것으로 하였고, JDK는 1.6이 설치되어 있다고 가정합니다.
먼저 각 프로그램, 라이브러리들을 해당 사이트에서 다운로드 합니다.
이제, Tocmat 6 와 PostgreSQL 8.3 을 설치한다. 어렵지 않게 설치가 될 것이다. Tomcat 6의 설치위치는 C:\Program Files\Apache Software Foundation\Tomcat 6.0 이며,
PostgreSQL 8.3 의 설치위치는 C:\Program Files\PostgreSQL\8.3 가 될 것이다.
웹어플리케이션을 위한 디렉토리(C:\Workspace\Project)를 생성한다.
Project 디렉토리 밑에는 src, WebContent 디렉토리도 생성한다.
당연히도, WebContent 디렉토리 밑에는 WEB-INF 디렉토리도 생성한다.
최종 디렉토리,파일의 전체 모습은 다음과 같다.

C:\Workspace\Project
                    \src
                        struts.xml
                        SqlMapConfig.xml
                        SqlMap_Admin.xml
                        \com
                             \test
                                  \action
                                         ListAdmin.java
                                  \dao
                                      AdminDao.java
                                  \model
                                        Admin.java
                                  \util
                                       SqlMapLocator.java
                    \WebContent
                               helloWorld.jsp
                               \admin
                                     listAdmin.jsp
                               \WEB-INF
                                       web.xml
                                       \lib
                                           commons-logging-1.0.4.jar
                                           freemarker-2.3.8.jar
                                           ibatis-2.3.4.726.jar
                                           ognl-2.6.11.jar
                                           struts2-core-2.0.14.jar
                                           xwork-2.0.7.jar
                                       \classes
                                               struts.xml
                                               SqlMapConfig.xml
                                               SqlMap_Admin.xml
                                               \com
                                                   \test
                                                        \action
                                                               ListAdmin.class
                                                        \dao
                                                            AdminDao.class
                                                        \model
                                                              Admin.class
                                                        \util
                                                            SqlMapLocator.class

이제 다운로드한 iBATIS 와 Struts2 파일을 압축풀고, 필요한 파일을 C:\Workspace\Project\WebContent\WEB-INF\lib 에 복사한다.
iBATIS 에서는 ibatis-2.3.4.726.jar 만 복사하면 되고, Struts2 에서는 commons-logging-1.0.4.jar, freemarker-2.3.8.jar, ognl-2.6.11.jar, struts2-core-2.0.14.jar, xwork-2.0.7.jar 을 복사한다.
그리고, PostgreSQL JDBC 드라이버는 C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib 에 복사해둔다.
이로써 필요한 프로그램 설치는 완료되었다.
원활한 테스트를 위해서 도메인 설정을 하자. C:\WINDOWS\system32\drivers\etc\hosts 파일을 열어서 아래 내용을 추가한다. 앞으로 test.com 을 웹브라우저에 입력하며 테스트할 것이다.

127.0.0.1       test.com

Tomcat 6 의 server.xml 을 설정해보자. 이 파일은 C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf 에 존재한다. 우선 67째 라인에 아래 내용을 찾아서 port를 8080에서 80으로 변경한다.

...
    <Connector port="80" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" />
...

그리고, 맨 밑부분에 닫힌 Host 태그를 찾아서 그 밑에 아래와 같이 버추얼호스팅 설정을 입력한다.

...
      <!-- test.com -->
      <Host name="test.com" debug="0" appBase="" unpackWARs="true" autoDeploy="true">
        <Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="test.com_" suffix=".log" timestamp="true"/>
        <Context path="" docBase="C:\Wrokspace\Project\WebContent" debug="0">
          <Resources className="org.apache.naming.resources.FileDirContext" allowLinking="true" />
          <Resource name="jdbc/TestDB"
                    auth="Container"
                    type="javax.sql.DataSource"
                    driverClassName="org.postgresql.Driver"
                    loginTimeout="10"
                    maxWait="5000"
                    username="아이디"
                    password="비밀번호"
                    testOnBorrow="true"
                    url="jdbc:postgresql://127.0.0.1/디비이름" />
        </Context>
      </Host>
...

위의 내용중 아이디, 비밀번호, 디비이름은 PostgreSQL 에서 사용할 적당한 것으로 정하면 된다. 아직은 DB 생성도, 사용자 생성도 하지 않았으니 상관은 없다.
이제 C:\Wrokspace\Project\WebContent에 hellowWorld.jsp 를 작성해서 웹페이지가 잘 열리는지 확인해 볼 차례이다.

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hello, World</title>
</head>
<body>
<h1>잘 보이십니까?</h1>
</body>
</html>

Tomcat6를 실행한후, 웹브라우저에서 http://test.com/ 을 입력해서 내용이 잘 보이면 성공!
이제, DB 생성, 사용자 생성, 테이블 생성을 해보겠습니다.
첫번째로 DB/사용자 생성을 합니다. 시작 → 프로그램 → PostgreSQL 8.3 → SQL Shell (psql) 메뉴를 선택하고 아래와 같이 입력합니다.

Server [localhost]:
Database [postgres]:
Port [5432]:
Username [postgres]:
postgres 사용자의 비밀번호: <설치시에 입력했던 비밀번호>
이것은 PostgreSQL의 대화식 터미널 psql 입니다. 버전: psql 8.3.8

사용법:  \copyright 저작권 정보
         \h SQL 명령어 도움말
         \? 내장 명령어 도움말
         \g 또는 명령 끝에 ; 쿼리 실행
         \q 마침

postgres=# create user garachi with password 'Rnadmsdlfndjwlsek';
CREATE ROLE
postgres=# create database garachidb with encoding='utf-8' owner garachi;
WARNING:  could not determine encoding for locale "Korean_Korea.949": codeset is
 "CP949"
상세정보:  Please report this to <pgsql-bugs@postgresql.org>.
CREATE DATABASE
postgres=# \q

아이디/비밀번호를 통해서 로그인할 수 있도록 하려면 별도로 설정을해야 합니다.
C:\Program Files\PostgreSQL\8.3\data 디렉토리의 pg_hba.conf 파일을 열어서 아래와 같이 설정하고, PostgreSQL을 재시작 합니다.

host    all         all         0.0.0.0           0.0.0.0           password
local   all         postgres                                        trust
local   all         all                                             password

다시 SQL Shell (psql)을 실행하여 아래와 같이 입력하여 테스트용 테이블을 생성한다.

Server [localhost]:
Database [postgres]: <디비이름>
Port [5432]:
Username [postgres]: <아이디>
아이디 사용자의 비밀번호: <비밀번호>
이것은 PostgreSQL의 대화식 터미널 psql 입니다. 버전: psql 8.3.8

사용법:  \copyright 저작권 정보
         \h SQL 명령어 도움말
         \? 내장 명령어 도움말
         \g 또는 명령 끝에 ; 쿼리 실행
         \q 마침

garachidb=> 
CREATE TABLE tb_admin
(
  id serial NOT NULL,
  "login" character varying(20) NOT NULL,
  passwd character varying(20) NOT NULL,
  "name" character varying(20) NOT NULL,
  register_date date NOT NULL,
  login_datetime timestamp without time zone,
  status_code character varying(4),
  email character varying(40),
  mobile_phone character varying(20),
  CONSTRAINT tb_admin_pkey PRIMARY KEY (id),
  CONSTRAINT tb_admin_login_key UNIQUE (login)
)
WITH (
  OIDS=FALSE
);

insert into tb_admin(login, passwd, name, register_date, status_code, email, mobile_phone)
values('yahoo', 'yahoo123', 'YAHOO...', '2009-11-11', '0000', 'yahoo@yahoo.com', '010-1111-2222');

insert into tb_admin(login, passwd, name, register_date, status_code, email, mobile_phone)
values('google', 'google123', 'GOOGLE...', '2009-11-11', '0000', 'google@gmail.com', '010-3333-4444');

해당 웹어플리케이션에서 스트럿츠를 사용할 수 있도록 web.xml 을 아래와 같이 작성한다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>TEST</display-name>
 
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>
      org.apache.struts2.dispatcher.FilterDispatcher
    </filter-class>
  </filter>
 
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
 
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

struts.xml 을 아래와 같이 작성한다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
  <package name="Test" extends="struts-default" namespace="/admin">
    <action name="ListAdmin" class="com.test.action.ListAdmin">
      <result name="success">/admin/listAdmin.jsp</result>
    </action>
  </package>
</struts>

이것은 웹브라우저에서 http://test.com/admin/ListAdmin.action 를 입력하면 /admin/listAdmin.jsp 를 보여주겠다는 의미를 가지고 있다.
Admin.java 를 아래와 같이 작성한다. 위에서 생성한 tb_admin 테이블에 대한 모델 클래스이다.

package com.test.model;
 
import java.util.Date;
 
public class Admin {
 private int  id;
 private String  login;
 private String  passwd;
 private String  name;
 private Date  register_date;
 private Date  login_datetime;
 private String  status_code;
 private String  email;
 private String  mobile_phone;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getLogin() {
  return login;
 }
 public void setLogin(String login) {
  this.login = login;
 }
 public String getPasswd() {
  return passwd;
 }
 public void setPasswd(String passwd) {
  this.passwd = passwd;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Date getRegister_date() {
  return register_date;
 }
 public void setRegister_date(Date registerDate) {
  register_date = registerDate;
 }
 public Date getLogin_datetime() {
  return login_datetime;
 }
 public void setLogin_datetime(Date loginDatetime) {
  login_datetime = loginDatetime;
 }
 public String getStatus_code() {
  return status_code;
 }
 public void setStatus_code(String statusCode) {
  status_code = statusCode;
 }
 public String getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
 public String getMobile_phone() {
  return mobile_phone;
 }
 public void setMobile_phone(String mobilePhone) {
  mobile_phone = mobilePhone;
 }
}

iBATIS는 라이브러리파일과, SqlMapConfig.xml, SqlMap.xml 로 구성이 되며, 라이브러리 파일은 위에서 lib 에 복사를 해두었다.
여기에서는 SqlMapConfig.xml 파일을 읽어서 SQL Map 을 얻어오는 클래스를 작성하게 된다.
SqlMapLocator.java 를 아래와 같이 작성한다.

package com.test.util;
 
import java.io.IOException;
import java.io.Reader;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
 
public class SqlMapLocator {
 public static SqlMapClient getMapper() {
  SqlMapClient sqlMapper;
  try {
   Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
   sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
   reader.close();
  }catch(IOException e) {
   // Fail fast.
   throw new RuntimeException("Something bad happend while building the SqlMapClient instance." + e, e);
  }
 
  return sqlMapper;
 }
}

SqlMapConfig.xml 을 아래와 같이 작성한다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
 PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
 "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
 
<sqlMapConfig>
  <transactionManager type="JDBC" commitRequired="false">
    <dataSource type="JNDI">
      <property name="DataSource" value="java:/comp/env/jdbc/TestDB"/>
    </dataSource>
  </transactionManager>
  <sqlMap resource="SqlMap_Admin.xml" />
</sqlMapConfig>

그리고, SqlMap_Admin.xml 을 아래와 같이 작성한다. 테스트를 위한 tb_admin 테이블의 모든 레코드를 Select 하는 문장만 있다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
 PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
 "http://ibatis.apache.org/dtd/sql-map-2.dtd">
 
<sqlMap>
  <typeAlias alias="Admin" type="com.test.model.Admin"/>
  <select id="AdminList" resultClass="Admin">
    SELECT id, login, passwd, name, register_date, login_datetime, status_code, email, mobile_phone
    FROM tb_admin
  </select>
</sqlMap>
</xml>

AdminDao.java 를 아래와 같이 작성한다.

package com.test.dao;
 
import java.sql.SQLException;
import java.util.List;
 
import com.test.model.Admin;
import com.test.util.SqlMapLocator;
 
public class AdminDao {
 private static AdminDao singleton;
 
 private AdminDao() {}
 
 public static AdminDao getInstance() {
  if(singleton == null)
   singleton = new AdminDao();
  return singleton;
 }
 
 @SuppressWarnings("unchecked")
 public List<Admin> list() throws SQLException {
  List<Admin> list = (List<Admin>)SqlMapLocator.getMapper().queryForList("AdminList");
  return list;
 }
}

ListAdmin.java 를 아래와 같이 작성한다.

package com.test.action;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import com.test.dao.AdminDao;
import com.test.model.Admin;
import com.opensymphony.xwork2.ActionSupport;
 
public class ListAdmin extends ActionSupport {
 private static final long serialVersionUID = 1L;
 private String message = "Hello~!";
 private AdminDao dao;
 private List<Admin> list = new ArrayList<Admin>();
 
 public String getMessage() {
  return message;
 }
 
 public void setMessage(String message) {
  this.message = message;
 }
 
 public ListAdmin() throws IOException {
  dao = AdminDao.getInstance();
 }
 
 public String execute() throws Exception {
  list = dao.list();
  return SUCCESS;
 }
 
 public List<Admin> getList() {
  return list;
 }
 
 public void setList(List<Admin> list) {
  this.list = list;
 }
}

마지막으로, listAdmin.jsp 를 아래와 같이 작성한다.

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>관리자</title>
</head>
<body>
<s:if test="list.size() <= 0"> 데이터가 없네요. ^^;</s:if>
<h1>관리자 목록</h1>
<table border="1" width="100%">
<tr>
  <th>번호</th>
  <th>아이디</th>
  <th>비밀번호</th>
  <th>이름</th>
  <th>등록일자</th>
  <th>로그인일시</th>
  <th>상태코드</th>
  <th>이메일</th>
  <th>핸드폰</th>
</tr>
<s:iterator value="list">
<tr>
  <td><s:property value="id"/></td> 
  <td><s:property value="login"/></td>
  <td><s:property value="passwd"/></td>
  <td><s:property value="name"/></td>
  <td><s:property value="register_date"/></td>
  <td><s:property value="login_datetime"/></td>
  <td><s:property value="status_code"/></td>
  <td><s:property value="email"/></td>
  <td><s:property value="mobile_phone"/></td>
</tr>
</s:iterator>
</table>
</body>
</html>

드디어 웹브라우저에서 http://test.com/admin/ListAdmin.action 을 입력하면 테이블에 입력되었던 데이터를 볼 수 있을 것이다.