Whiteship's Note


Tag를 만들어 쓰면 좋은 이유



1. 유지 보수가 편해집니다.
=> 한 곳(Tag를 정의한 곳)에서 수정을 하면 싹~ 바뀌기 때문에 편리합니다. 물론 화면에 특화 시켜서 Tag를 잘 정의 해 놓았기 때문에 가능한 일일 것입니다.

2. 웹 표준을 지키는데 유리해 집니다.
=> 웹 표준 담당자가 Tag 정의 한 부분을 손봐 주시고 다른 개발자는 신경쓰지 않고 개발을 해도 됩니다. Seperation of Concern이 이루어 지는거죠.

3. 성능에는 문제가 없습니다.
=> 처음에 자바 파일을 컴파일 해야 하기 때문에 조금 느리지 그 이후로는 오히려 컨테이너에서 캐슁하고 있기 때문에 HTML 태그를 쓰는 것보다 빠르다고 합니다.

4. 코드의 가독성이 높아집니다.
=> 화면에 특화 시켜서 나눠 놓았기 때문에 눈에 훨씬 잘 들어오겠죠.

5. 기타 등등등...
=> 좋은 것 같아요.

top

TAG tag

Write a comment.


1-8. Hibernate Application 에서 사용되는 객체의 상태



사용자 삽입 이미지

Hibernate In Action 4.1.1 Transient Object 처음에 나오는 그림입니다. Hibernate에서 사용되는 객체의 상태 변화를 보여주고 있습니다.
  • Transient는 DB와 아무 연관이 없는 상태입니다.
  • Persistent는 DB와 동기화 되어 있는 상태입니다.
  • Detached는 DB와 동기화 된 적이 있는 상태입니다.
소스코드와 연관 시켜 보겠습니다.
        Pizza pizza = new Pizza();
        pizza.setName("ines's pizza");
        pizza.setPrice(10000);
        pizza.setSize("Large");
        pizza.setToping("Kimchi");

        s.save(pizza);

        pizza.setPrice(15000);

        tx.commit();
        s.close();

        pizza.setPrice(20000);

위 소스크드와 그림을 보시면서 Pizza 객체의 상태를 추적해 보겠습니다. 먼저 new를 하여 객체를 생성하게 되면 이 객체는 transient 상태가 됩니다. 그 후에 s.save(pizza);를 하게 되면 Persistent 상태가 되는데 그렇기 때문에 이 전 글에서 s.update(pizza); 를 호출하지 않아도 DB와 동기화 되어 있는 상태이기 때문에 update가 된 것 같습니다. 그 뒤 s.close()를 호출하면 그 뒤 부터는 DB와 동기화 된 적은 있지만 현재는 그렇지 않은 Detached 상태가 됩니다.
new를 만나면 Transient => save() 이후 부터는 Persistent => close() 이후 부터는 Detached 상태 입니다.

Transient 상태와 Detached 상태의 차이점은 Transient 상태에서 Pizza의 pizzaId라는 속성은 null인 상태입니다. 하지만 Detached 상태는 DB와 동기화 된 적이 있기 때문에 pizzaId 속성에 값을 가지고 있습니다.

top

Write a comment.


1-7. 레코드 update 하기



PizzaApp의 내용을 다음과 같이 수정합니다.
Pizza pizza = new Pizza();
        pizza.setName("yuonghoe's pizza");
        pizza.setPrice(10000);
        pizza.setSize("Large");
        pizza.setToping("Pepperoni");

        s.save(pizza);

        pizza.setPrice(15000);
        s.update(pizza);
처음에 가격을 만원으로 했다가 너무 낮아서 만오천원으로 올리고 s.update(pizza); 메소드를 사용하여 update를 합니다.

실행시키면 콘솔 창에 다음과 같이 출력됩니다.
Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)
Hibernate: update O_Pizza set toping=?, price=?, name=?, size=? where pizzaId=?

사용자 삽입 이미지

DB를 확인해 본 결과 15000원으로 update된 것을 확인 할 수 있습니다.

PizzaApp에서 작성한 코드에서 s.update(pizza);를 삭제하고 다음과 같이 입력해 보겠습니다.
        Pizza pizza = new Pizza();
        pizza.setName("chanwook's pizza");
        pizza.setPrice(10000);
        pizza.setSize("Large");
        pizza.setToping("Kimchi");

        s.save(pizza);

        pizza.setPrice(15000);

s.update(pizza); 가 빠진것을 제외하면 다른 부분은 거의 동일합니다. 이 것을 실행시키면 콘솔창에 다음과 같이 출력이 되고 DB에서 확인을 해도 역시 update 된 것을 확인할 수 있습니다.
Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)
Hibernate: update O_Pizza set toping=?, price=?, name=?, size=? where pizzaId=?

사용자 삽입 이미지

왜 이럴지는 HIA 4장에 나오는 그림을 보며 생각해 보겠습니다.
top

TAG Update

Write a comment.


1-6. 모델 클래스 수정하기



Pizza 클래스에 새로운 필드를 추가해 봅니다.

toping이라는 멤버를 추가하고 역시 어노테이션을 사용하여 @Column으로 지정해 줍니다. 그리고 getter, setter를 만들어 준뒤 PizzaApp 클래스에 적당한 값들로 세팅해 주고 save를 해봅시다.

그리고 PizzaApp를 실행 시키면 다음과 같이 새로운 필드가 생기고 기존에 있던 data들은 새로운 필드에 null값이 들어간 상태로 바뀝니다.

Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)

사용자 삽입 이미지

여기서 궁금한건..만약에 새로 만든 필드의 Column 속성에서 nullable을 false로 하면 어떻게 될까요? 해보면 되겠죠?

pgAdmin에서 table을 전부 날려버리고 Pizza 클래스에 추가했던 toping 멤버를 삭제하고 게터와 세터로 삭제합니다. 그리고 name, size, price만 넣어 줍니다.
사용자 삽입 이미지

이 상태에서 이제 다시 Pizza 클래스에 Toping을 추가하고 이번에는 @Column(nullable=false)로 설정을 해줍니다. 그리고 PizzaApp에서는 새로운 레코드를 추가합니다.
그리고 실행을 하면 다음과 같은 메시지가 콘솔창에 출력됩니다.

Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)

엇... DB로 확인해 봤더니 toping이라는 컬럼이 추가 되었고 새로운 레코드도 입력 되었습니다. 하지만 기존에 있던 레코드는 새로 생긴 컬럼이 null로 되어있습니다.

사용자 삽입 이미지

오호~~~table을 생성하는 쿼리를 살펴봤더니 toping 컬럼을 만들 때 not null을 넣지 않았군요. Hibernate 가 마치 '이정도 쯤이야' 하며 으쓱해 하는 기분이군요. 새로 추가되는 필드는 nullable=false로 하더라도 무시 됩니다. 그리고 그렇게 처리하는 것이 논리적인 것 같습니다.

사용자 삽입 이미지

top

Write a comment.


1-5. 모델 사용하기



앞에서 만든 모델을 사용하는 간단한 어플리케이션을 만들기 위해 src밑에 app라는 패키지를 만들고 그안에 PizzaApp 클래스를 만듭니다.

package app;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PizzaApp {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                new String[] { "applicationContext-dao.xml",
                        "applicationContext-jdbc-datasource.xml" });
        SessionFactory sf = (SessionFactory) ac.getBean("sessionFactory");

        Session s = sf.openSession();
        Transaction tx = s.beginTransaction();

        //TODO 할일

        tx.commit();
        s.close();
    }
}

녹색 부분은 Spring을 사용하여 session 팩토리를 받아옵니다. 역시 전 Session Factory도 처음 보는 것이기 때문에 이 부분도 공부가 필요합니다.
파란색 부분은 세션 팩토리를 사용하여 세션을 열고 닫는 부분입니다.
보라색 부분은 세션으로 부터 트랜잭션을 시작하고 완료 시키는 부분입니다.

세션을 열고 트랜잭션 시작한 뒤에~ 하고 싶은 일을 하면 됩니다. 먼저 Pizza 객체를 생성하여 DB에 저장을 해봅니다.
        Pizza pizza = new Pizza();
        pizza.setName("keesun's pizza");
        pizza.setPrice(200);
        pizza.setSize("BIG");
위와 같이 코딩을 하고 저장을 하겠다는 의미로
    s.save(pizza);
이렇게 하면 DB에 들어가게 될 것입니다.

기대를 품고 실행을 하면 다음과 같은 에러를 볼 수 있습니다.

postgres JDBC를 빌드 경로에 추가하지 않아서 발생한 에러입니다. 적절한 조취를 취한 뒤[각주:1] 다시 실행시키면~

1-3. 기본 설정 하기
에서 유심히 보신 분은 눈치 채셨겠지만 applicationContext-dao.xml 의  sessionBean 설정에서 '뭔가 들어가야 할 부분'에 다음의 코드를 넣습니다.
<property name="annotatedClasses">
            <list>
                <value>model.Pizza</value>
            </list>
</property>

어노테이션이 사용된 클래스를 등록해 주는 것 같습니다. 그리고 이제 프로그램을 실행시키면 커맨드 창에서 다음의 메시지를 확인 할 수 있습니다.

Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (price, name, size, pizzaId) values (?, ?, ?, ?)

그리고 DB에서 확인하면 다음과 같이 Table이 생기고 data가 들어간 것을 확인 할 수 있습니다.

사용자 삽입 이미지

정말 마술 같은 쑈입니다. :) DB와 SQL에 손도 안대고 table을 만들고 데이타를 넣다니..허허허;;;
  1. postges설치 경로 / 8.1 / jdbc / postgresql-8.1-405.jdbc3.jar 를 lib에 복사한 뒤 빌드 경로에 추가 해줌 [본문으로]
top

  1. Favicon of http://chanwook.tistory.com/ BlogIcon 찬욱 2006.12.27 10:30 PERM. MOD/DEL REPLY

    부러워요!!
    혼자 이런걸 하다니!

    안그래도 Hibernate 하면서 annotation 으로 공부하고 싶었는데 눈팅으로 공부하면 되겠군요..
    으흐흐..

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2006.12.27 11:33 PERM MOD/DEL

    오픈시드에 내가 체험한 강의가 그대로 올라와 있으니 그걸 보면되지.
    아직 정리를 못한 내용도 그곳에 올려진 파일에 있어.ㅋㅋ

Write a comment.


1-4. 모델 만들기



src에 model패키지를 추가하고 간단한 POJO 클래스를 만들어 봅니다.

현재 살짝 졸린데 배까지 고픈 관계로 Pizza 클래스를 만들기로 하겠습니다. 속성으로는 고유한 값에 해당하는 pizzaId, size, name, price 이렇게 네가지가 있습니다.

매우 단순한 클래스가 만들어졌습니다. 이제 이 클래스에 어노테이션을 적용합니다. 어노테이션을 적용하게 되면 테이블과 매핑이 이뤄집니다.

사용자 삽입 이미지
이때 주의 할 점은 방언에 해당하는 org.hibernate.annotations에 있는 어노테이션 말고 차후 확장성을 고려하여 javax.persistence에 있는 어노테이션을 사용하기 입니다.

각 어노테이션에 지정할 수 있는 속성이 보고 싶을 땐 이클립스에서 원하는 어노테이션에서 f4를 누르면 왼쪽 hierarchy 창에서 보입니다.

여기서 사용한 어노테이션으로는 Entity, Id, Column, SequenceGenerator, GeneratedValue입니다. 각각에서 사용가능한 속성들에 대한 공부도 필요할 것 같습니다.
top

Write a comment.


1-3. 기본 설정 하기



src 폴더에 파일 두 개를 생성합니다. 하나는 log4j.properties 하나는 database.properties 입니다. log4j.properties파일은 logging과 관련된 설정파일이고 database.properties는 db 연결을 설정하는 것과 관련된 설정파일 같습니다. database.properties의 내용은 다음과 같습니다.

#
# data source jdbc connection
#

db.driver=org.postgresql.Driver
db.url=jdbc:postgresql:webapp2
db.username=postgres
db.password=webapp2


#
# hibernate
#

hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

녹색 부분은 db 커넥션을 생성하기 위해 필요한 정보이고 아래 dialect는 hibernate가 각 db가 사용하는 SQL 방언을 사용하려면 그에 맞는 SQLDialect를 사용하도록 지정해 주는 부분이라고 합니다. 현재 DB는 PostgreSQL을 사용할 것이기 때문에 위와 같이 설정해 두었습니다.

pgaAdmin을 실행시켜서 본인이 사용하시는 환경과 커넥션 설정 부분을 일치 시켜줘야 할 것 같습니다.

src 폴더에 spring을 사용하기 위해 두 개의 파일을 추가로 생성합니다.
먼저 applicationContext-jdbc-datasource.xml 파일을 추가합니다.

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:database.properties</value>
            </list>
        </property>
    </bean>
   
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${db.driver}"/>
        <property name="jdbcUrl" value="${db.url}"/>
        <property name="user" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
    </bean>

오호.. 덩달아 Spring 공부도 하게 됩니다. 기쁘군요. :) 앞에 정의한 db 커넥션 부분을 가져와서 dataSource에 설정하는 곳에서 사용하고 있습니다.

다음으로 applicationContext-dao.xml 파일을 추가합니다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="byName">
    <!-- ================================================================ -->
    <!--                       SessionFactory                             -->
    <!-- ================================================================ -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" autowire="no">
        <property name="dataSource" ref="dataSource" />
        <!-- 요 사이에 나중에 뭔가 들어갑니다. --!>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" autowire="no">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

녹색 부분은 앞서 정의한 dialect 설정을 적용하는 것이고 show_sql을 true로 하면 실행이 될 때 콘솔창에 실행되는 sql문을 보여줍니다. hbm2ddl.auto를 update로 해두면 DB의 테이블을 매핑하고 있는 파일이 바뀌면 테이블도 바뀌게 된다고 합니다. 이 부분에 대한 설명을 찾아보니 다음과 같이 적혀 있습니다.

Automatically validate or export schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.
출처 : http://www.hibernate.org/hib_docs/v3/reference/en/html/session-configuration.html

이제 설정은 끝났습니다.
top

  1. 이은주 2007.01.09 08:47 PERM. MOD/DEL REPLY

    정리가 많이 도움됩니다.
    죄송하지만 postgresSQL 사이트 링크가 제대로 않되서 그러는데..
    받아놓으신거 있음 좀 보내주실 수 있을까요?
    pgAdmin III 도...있으시면..
    julee72@paran.com

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2007.01.09 09:10 PERM MOD/DEL

    네. 도움이 되셨다니 감사합니다.

    흠.. 링크는 제대로 되는것 같습니다.
    http://wwwmaster.postgresql.org/download/
    이곳에 가셔서 다운을 받으셔도 되지만..
    보내드리겠습니다. :)

Write a comment.


1-2. 필요한 라이브러리들 추가



먼저 Eclise에서 프로젝트를 생성합니다. 저는 study로 생성하고 소스폴더는 src와 test를 만들겠습니다. 그리고 필요한 라이브러리 파일들을 모아두기 위해 lib라는 폴더를 만들겠습니다.

물개 선생님께서 앞으로 사용하게 될 라이브러리 목록들을 정리해 주셨습니다.
- hibernate-3.2 / hibernate3.jar
- hibernate-3.2 / lib / ant-antlr-1.6.5.jar
- hibernate-3.2 / lib / antlr-2.7.6.jar
- hibernate-3.2 / lib / c3p0-0.9.0.jar
- hibernate-annotations-3.2.1.GA / hibernate-annotations.jar
- spring-framework-2.0.1 / dist / spring.jar
- spring-framework-2.0.1 / dist / modules / spring-hibernate3.jar
- spring-framework-2.0.1 / lib / cglib / cglib-nodep-2.1_3.jar
- spring-framework-2.0.1 / lib / jakarta-commons / commons-collections.jar
- spring-framework-2.0.1 / lib / jakarta-commons / commons-logging.jar
- spring-framework-2.0.1 / lib / dom4j / dom4j-1.6.1.jar
- spring-framework-2.0.1 / lib / jpa / persistenec.jar (JPA)
- spring-framework-2.0.1 / lib / ehcache / ehcache-1.2.3.jar
- spring-framework-2.0.1 / lib / j2ee / jta.jar
- spring-framework-2.0.1 / lib /log4j / log4j-1.2.14.jar
- junit4.1 / junit-4.1.jar
C:/Program Files/PostgreSQL/8.1/jdbc/postgresql-8.1-405.jdbc3.jar
각각의 jar파일들이 어떤 곳에 필요한지는 공부가 필요한 상태입니다. 위 jar파일들을 찾아서 lib폴더로 복사줍니다.

프로젝트에서 lib폴더 안에 있는 jar파일을 모두 선택해 주고 오른쪽 마우스를 클릭하여 Add to BuildPath를 클릭하여 빌드 경로에 추가해 줍니다.

사용자 삽입 이미지

top

Write a comment.


1-1. 프로젝트 관련 라이브러리 다운로드



OpenSeed Forum 인덱스OpenSeed Forum 인덱스OpenSeed Forum 인덱스OpenSeed Forum 인덱스OpenSeed Forum 인덱스
http://www.openseed.net/forum/ 이곳에서 만난 teacher.seal께 배운 강좌에 대한 복습이 시작 됩니다.

Hibernate와 Spring을 사용하여 간단한 프로젝트를 구성할 때 필요한 파일들을 다운로드 합니다.

먼저 Hibernate관련 소스는 http://www.hibernate.org/6.html 이곳에서 Hibernate Core와 Hibernate Annotations를 다운로드합니다.
사용자 삽입 이미지

Spring 소스는 http://www.springframework.org/download 이곳에서 2.0.1버젼의 download를 클릭한 뒤 with-dependencies를 다운로드 합니다.
사용자 삽입 이미지
거의 60MB 정도 합니다.[각주:1] 셋 중에서 덩치가 가장 크군요.

마지막으로 JUnit은 http://www.junit.org/index.htm 이곳의 상단 왼쪽에 download 메뉴를 클릭하면 자동으로 최신 버젼 다운로드를 할 수 있습니다.
사용자 삽입 이미지

아! 그리고 한가지 더! 사용할 DB에 따른 JDBC jar파일이 필요합니다. 물개 선생님과 예제 실습을 Postgres로 진행하기로 했습니다. 따라서 postgres로 다운 받아서 설치하셔야합니다.
http://www.postgresql.org/ftp/pgadmin3/release/v1.6.1/win32/ 이곳에서 다운로드를 하시고 설치를 하시면 됩니다.

Postgres를 제외한 다른 파일들은 D:\study\openSources 폴더 안에 모아두고 전부 압축을 풀었습니다.

사용자 삽입 이미지

일단 이것으로 준비물은 다 챙긴것 같습니다. :) 집에간 뒤에 계속하겠습니다.

top

  1. Favicon of https://seal.tistory.com BlogIcon 물개선생 2006.12.27 01:43 신고 PERM. MOD/DEL REPLY

    허곡, 너무 부지런하신 것 아닙니까? 쵝오 입니다.. ^^*

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2006.12.27 02:05 신고 PERM MOD/DEL

    휴~ 빨리 정리하지 않으면 금방 잊어버릴것 같아서요.
    다행히 기억에서 놓칠 뻔한 것(hibernate.hbm2ddl.auto)도 있었는데 상당부분 많이 건졌습니다.

    오늘 강의 정말 최고였습니다. 귀와 눈과 머리로 쏙쏙 들어옵니다. :)

Write a comment.