블로그 이미지

카테고리

분류 전체보기 (11)
Programming (6)
Baskek Ball (0)
Diary (2)
etc (1)
Picture (2)
Total
Today
Yesterday
02-16 01:41

달력

« » 2025.2
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

공지사항

태그목록

최근에 올라온 글

윈도우즈에서 타 OS가 설치된 서버(Linux, Solaris)를 Telnet, SSH가 아닌 GUI로 작업할 수 있도록 하는 대표적인 툴로 Xmanager가 있다. 하지만 Xmanager의 경우는 라이센스를 구매하거나 30일 평가판으로 사용해야 하기 때문에

Xming을 사용하여 Xmanaer의 XDMCP기능을 사용해 보자.

Putty를 먼저 설치하는 이유는 Xming 설치 중에 Putty를 자동으로 연동시키기 때문에 추후에 경로 설정하는 번거로움을 피하기 위함이다.

Putty의 설치가 완료 되면 Xming을 설치한다. (http://sourceforge.net/projects/xming/)
Xming을 설치한 후에 X- font도 설치한다.
 



Putty와 Xming의 설치가 모두 끝났으면, XLaunch를 실행한다.

아래는 XDMCP를 사용하기 위한 XLaunch 설정 화면이다.

1. Multiple Windows의 경우 X11등 SSH를 사용하기 위한 것이다.
XDCMP를 사용하기 위해서는 One window를 선택.

2. 세가지 선택중 가장 밑에 있는 Open session via XDMCP를 선택.

3. XDCMP를 사용하여 접속하고자 하는 HOST의 주소를 파란 박스 안에 입력.

 4. Clipboard등의 설정을 하는 화면. 별다른 설정이 필요 없음.

 5. 마지막 설정화면.
반드시! Save Confguration을 클릭하여 현재 설정상태를 저장한다.



 
5번째 설정화면에서 Save Configuration을 하여 설정파일을 저장해야 하는 이유는
Xmanager와 달리 Xming의 경우는 저장된 설정파일을 실행해야하기 때문이다.

XDMCP를 한번만 접속하고 마는 경우에는 설정파일을 저장할 필요가 없지만,
접속을 자주 하는 경우에는 접속할 때마다 설정을 하는 번거로움을 줄이기 위함이다.

그리고 설정파일을 저장할 경우 확장자가 제대로 지정되지 않는 경우가 발생하는데
실행하는 데에는 문제가 없지만 매번 연결프로그램을 선택해야 하는 번거로움이 발생하는데,
설정파일의 확장자 명을 .xlaunch로 지정하게 되면 연결프로그램을 선택하는 수고를 덜어 준다.

확장자 설정 전 → 확장자 설정 후



다음 화면이 Xming으로 리눅스 서버의 XWindow를 실행한 모습이다. 

 

'Programming > etc' 카테고리의 다른 글

SVN 서버 변경시 프로젝트 이동 방법  (0) 2011.09.08
FAT Jar Exporter  (0) 2011.09.08
Posted by 그리브스
, |

Old SVN에 등록되어 있는 소스 프로젝트를 New SVN에 등록해야 하는 경우가 있다.

Old SVN에 연결해서 사용하던 프로젝트를 Disconnect한 후에 New SVN에 등록하는 방법을 다음에서 알아보자.

이동해야할 프로젝트를 선택한 후 마우스 우클릭 -> Team -> Disconnect를 선택하게 되면  아래와 같은 선택창이 나온다.

SVN의 정보(revision)을 삭제할 것인지 보존할 것인지를 선택하는 것이다.
 ◎ Also delete the SVN meta-informaion from the file system : revision 및 sub디렉토리 제거
 ◎ Do not delete the SVN meta-informaion(e.g. .svn subdirectories) : sub 디렉토리등의 정보 미삭제

위의 방법을 마치면 프로젝트와 SVN간의 연결 끊어지고 일반 자바프로젝트와 같은 프로젝트가 된다.


New SVN에 프로젝트를 연결하는 방법은 일반 프로젝트를 SVN에 등록하는 방법과 동일하다.

프로젝트 선택 -> 마우스 우클릭 -> Team -> Share Project

Share Project를 선택하게 되면 위와 같은 창이 보인다. 이때 SVN을 선택하고 Next를 하게 되면
SVN URL 및 Directory를 선택하고 사용자 인증을 하게되면,

새로운 SVN 서버에 프로젝트가 등록이 된다. 

'Programming > etc' 카테고리의 다른 글

Xmanager 대신 사용할수 있는 Xming.  (0) 2011.09.19
FAT Jar Exporter  (0) 2011.09.08
Posted by 그리브스
, |

FAT Jar Exporter

Programming/etc / 2011. 9. 8. 09:11
Eclipse Plugin으로 자바 프로젝트를 라이브러리 처럼 사용할 수 있도록 .Jar 형식으로 묶어주는 역할을 함.

프로젝트에 포함된 Library 및 .java 파일을 컴파일 하여 Jar파일로 만드는 일을 함. 

'Programming > etc' 카테고리의 다른 글

Xmanager 대신 사용할수 있는 Xming.  (0) 2011.09.19
SVN 서버 변경시 프로젝트 이동 방법  (0) 2011.09.08
Posted by 그리브스
, |

Generic이란 무엇일까요? Java 1.5 버전부터 나온 새로운 문법입니다미결정된 선언을 컴파일 타임으로 미루므로써

프로그래밍의 유연성을 부여할 수 있게 되었습니다말이 좀 이상한데 한번 보면 될듯합니다.

 

일반적으로 insert, select, update, delete는 기본적으로 작성해야 되므로 이를 Abstract로 뽑아내어 공통으로 사용하고

필요한 것들만 만들어 사용하면 프로그램의 생산성이 향상되겠죠근데 이때 문제가 여러 개의 vo는 서로 다른 형태를

취하고 있으므로 이를 공통을 맞춰줄 수가 없게 됩니다이때 Generic을 사용하여 문제를 해결할 수 있습니다. Generic

class파일을 생성하는 compile타임에 실제 선언된 타입으로 컴파일 됩니다.

package org.power.dao;

 

public interface GenericDAO<V, K> {

 

       public void insert(V vo) throws Exception;

       public V select(K key) throws Exception;

       public void update(V vo) throws Exception;

       public void delete(K key) throws Exception;

}

 

공통으로 사용되는 코드를 Generic을 사용하여 Abstract로 구현해 보았습니다.

package org.power.dao;

 

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 AbstractDAO<V, K> implements GenericDAO<V, K>{

      

       protected static SqlMapClient sqlMap;

       protected String namespace;

      

       static {

 

             try {

                    Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");

                    sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

                    reader.close();

             catch (IOException e) {

                    // Fail fast.

                    throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);

             }

       }

      

       @Override

       public void insert(V vo) throws Exception {

             sqlMap.insert(namespace + ".insertBBS", vo);

            

       }

 

       @Override

       public V select(K key) throws Exception {

             return (V) sqlMap.queryForObject(namespace + ".selectBBS", key);

       }

 

       @Override

       public void update(V vo) throws Exception {

            

             sqlMap.update(namespace + ".updateBBS", vo);

            

       }

 

       @Override

       public void delete(K key) throws Exception {

             sqlMap.delete(namespace + ".deleteBBS", key);

            

       }

      

}

 

위에 namespace가 있습니다이는 서로 다른 성격의 insert, select, update, delete작업을 하는 xml의 분리하기 위해 사용됩니다.

그러므로 xml도 해당 namespace를 설정해 주어야 합니다.

 

<?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>

 

       <settings useStatementNamespaces="true"/>

      

       <transactionManager type="JDBC" commitRequired="false">

             <dataSource type="SIMPLE">

                    <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver"/>

                    <property name="JDBC.ConnectionURL"value="jdbc:oracle:thin:@127.0.0.1:1521:ORCL" />

                    <property name="JDBC.Username" value="tony" />

                    <property name="JDBC.Password" value="1234" />

             </dataSource>

       </transactionManager>

 

       <sqlMap resource="BBS.xml" />

 

</sqlMapConfig>

 

 

<?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 namespace="BBS">

      

 

       <insert id="insertBBS" parameterClass="org.power.vo.BbsVO">

             <![CDATA[

                    INSERT INTO TBL_BBS (bbsno, title, content, writer, hits)

                    VALUES (SEQ_BBS_NO.NEXTVAL, #title#, #content#, #writer#, #hits#)

             ]]>

       </insert>

      

       <select id="selectBBS" resultClass="org.power.vo.BbsVO">

             <![CDATA[

                    SELECT bbsno, title, content, writer, hits, regdate

                    FROM TBL_BBS

                    WHERE bbsno = #bbsno#

             ]]>

       </select>

      

       <update id="updateBBS" parameterClass="org.power.vo.BbsVO">

             <![CDATA[

                    UPDATE TBL_BBS SET title=#title#, content=#content#,

                    writer=#writer#, hits=#hits#, regdate=#regdate#

                    where bbsno=#bbsno#

             ]]>

       </update>

      

       <delete id="deleteBBS" parameterClass="java.lang.Integer">

             <![CDATA[

                    DELETE FROM TBL_BBS WHERE bbsno=#bbsno#

             ]]>

       </delete>

      

</sqlMap>

 

 

 

BbsDAO를 만들어 보겠습니다즉 게시판 하나가 되겠지요아래에 보면 선언된 인터페이스가 하나도 없죠이는GenericDAO에서

선언되어 있으며 BbsDAO에서는 해당 코드를 물려 받습니다다만 여기서 중요한 것이 파라메터값이 확정된다는 것입니다.

package org.power.dao;

 

import org.power.vo.BbsVO;

 

public interface BbsDAO extends GenericDAO<BbsVO, Integer> {

      

       //만약 insert, select, update, delete 이외의 DAO메소드가 필요하다면 여기에

       //인터페이스를 선언하고 Implements하면 됩니다.

      

}

 

구현 클래스를 보면 아래와 같습니다기본적으로 Abstract의 코드를 물려 받으므로 BbsDAO와 같이 BbsDAOImpl에도 별다른 코드가

없습니다다만 여기서 namespace를 결정해 주어야 합니다.

package org.power.dao;

 

import org.power.vo.BbsVO;

 

public class BbsDAOImpl extends AbstractDAO<BbsVO, Integer> implements BbsDAO {

 

       public BbsDAOImpl() {

             super();

             namespace = "BBS";

       }

      

       //BbsDAO에서 기본 insert, select, update, delete외에 DAO 메소드를 추가하였다면

       //이부분에 구현을 해주시면 됩니다.

      

}

 

자 이제 DAO를 테스트 해보기로 하겠습니다테스트 코드는 기존과 동일합니다.

package org.power.test;

 

import org.power.dao.BbsDAO;

import org.power.dao.BbsDAOImpl;

import org.power.vo.BbsVO;

 

import junit.framework.TestCase;

 

public class BbsDAOTest extends TestCase {

 

       private BbsDAO bbsDao;

 

       protected void setUp() throws Exception {

             super.setUp();

 

             bbsDao = new BbsDAOImpl();

 

       }

 

       public void testInsert() {

 

 

             BbsVO vo = new BbsVO();

 

             try {

 

                    vo.setTitle("Generic 사용한 설계새로운 글을 등록합니다.(타이틀)");

                    vo.setContent("Generic 사용한 설계새로운 글을 내용을합니다.");

                    vo.setHits(100);

                    vo.setWriter("S002");

 

                    bbsDao.insert(vo);

 

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

 

       }

 

       public void testSelect() {

 

             BbsVO vo = new BbsVO();

 

             try {

                    vo = bbsDao.select(700);

 

                    System.out.println(vo.getBbsno());

                    System.out.println(vo.getTitle());

                    System.out.println(vo.getContent());

                    System.out.println(vo.getWriter());

                    System.out.println(vo.getRegdate());

 

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

 

       }

 

       public void testUpdate() {

 

             BbsVO vo = new BbsVO();

 

             try {

 

                    vo = bbsDao.select(600);

 

                    vo.setTitle("800  타이틀 수정입니다.");

                    vo.setContent("800  내용 수정한 내용입니다");

                    vo.setHits(0);

 

                    bbsDao.update(vo);

 

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

 

       }

 

       public void testDelete() {

 

             try {

 

                    bbsDao.delete(1000);

 

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

 

       }

 

}

 

 

Insert 정상적으로 작동함.

 

Select 정상적으로 작동합니다.

 

이제 완성하였습니다자 그러면 새로운 테이블이 생성되고 똑 같은 기능의 게시판을 만든다고 했을 때는 새로운 인터페이스만 선언하고 xml파일만 만들어주면 새로운 게시판이 생성될 것입니다.


[출처] http://blog.naver.com/byebird


 

'Programming > Java' 카테고리의 다른 글

Ibatis 라이브러리를 이용한 VO,DAO의 구현  (0) 2011.07.19
JDBC를 이용한 VO,DAO의 구현  (0) 2011.07.19
Posted by 그리브스
, |

전에 JDBC를 이용하여 VO, DAO설계를 해보았습니다. 그러다 보니 많은 부분 불필요한 소스가 생겨나고 생산성이 떨어지는 것을 경험하였을 것입니다. 이를 해결하기 위하여 Ibatis라는 라이브러리를 사용해 보겠습니다.

Ibatis는 JDBC를 대체하는 것이 아니라 JDBC를 효율적으로 사용하는 라이브러리라 할 수 있습니다. 그 핵심에는 DI(Dependency injection)패턴이 있습니다. 각종 프레임워크에서는 이 DI를 적극적으로 활용하고 있으며 특히 Java 1.5부터는 Annotation을 활용하여 DI가 기본을 이루고 있습니다. DI패턴과 Annotation은 나중에 알아 보고요.

우선은 ibatis를 활용하여 vo와 dao를 구현해보겠습니다.

 

테이블과 vo, dao인터페이스는 기존 생성은 기존과 같습니다.

package org.power.vo;

 

import java.util.Date;

 

public class BbsVO {

      

       private int bbsno;

       private String title;

       private String writer;

       private int hits;

       private String content;

       private Date regdate;

      

       public int getBbsno() {

             return bbsno;

       }

       public void setBbsno(int bbsno) {

             this.bbsno = bbsno;

       }

       public String getTitle() {

             return title;

       }

       public void setTitle(String title) {

             this.title = title;

       }

       public String getWriter() {

             return writer;

       }

       public void setWriter(String writer) {

             this.writer = writer;

       }

       public int getHits() {

             return hits;

       }

       public void setHits(int hits) {

             this.hits = hits;

       }

       public String getContent() {

             return content;

       }

       public void setContent(String content) {

             this.content = content;

       }

       public Date getRegdate() {

             return regdate;

       }

       public void setRegdate(Date regdate) {

             this.regdate = regdate;

       }

      

}

 

package org.power.dao;

import org.power.vo.BbsVO;

 

public interface BbsDAO {

      

       public void insert(BbsVO vo) throws Exception;

       public BbsVO select(int bbsno) throws Exception;

       public void update(BbsVO vo) throws Exception;

       public void delete(int bbsno) throws Exception;

      

}

 

자 그럼 Ibatis 라이브러리를 활용하여 구현을 해볼까요우선 공통적으로 Ibatis 환경설정 부분을 Abstract Class로 빼 보았습니다그냥 구현해도 되지만 확장성을 고려해서 빼보겠습니다.

package org.power.dao;

 

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 abstract class AbstractIbatis {

      

       protected static SqlMapClient sqlMapper;

        

       static {

           try {

             Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");

             sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);

             reader.close();

           catch (IOException e) {

             // Fail fast.

             throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);

           }

         }

 

}

 

SqlMapConfig.xml 환경설정 파일은 아래와 같습니다여기서 JDBC Connection 정보를 설정하는 곳이 보입니다.

, Ibatis JDBC를 쉽게 사용하기 위한 툴입니다여기서 확인해 두어야 할 것은 sqlMap 테그 부분으로 SQL문장을따로 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="SIMPLE">

                                        <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver" />

                                        <property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@127.0.0.1:1521:ORCL" />

                                        <property name="JDBC.Username" value="tony" />

                                        <property name="JDBC.Password" value="1234" />

                           </dataSource>

             </transactionManager>

 

             <sqlMap resource="BBS.xml" />

 

</sqlMapConfig>

 

BBS.xml의 내용을 보면 아래와 같다.

<?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>

 

       <insert id="insertBBS" parameterClass="org.power.vo.BbsVO">

             <![CDATA[

                    INSERT INTO TBL_BBS (bbsno, title, content, writer, hits)

                    VALUES (SEQ_BBS_NO.NEXTVAL, #title#, #content#, #writer#, #hits#)

             ]]>

       </insert>

      

       <select id="selectBBS" resultClass="org.power.vo.BbsVO">

             <![CDATA[

                    SELECT bbsno, title, content, writer, hits, regdate

                    FROM TBL_BBS

                    WHERE bbsno = #bbsno#

             ]]>

       </select>

      

       <update id="updateBBS" parameterClass="org.power.vo.BbsVO">

             <![CDATA[

                    UPDATE TBL_BBS SET title=#title#, content=#content#,

                    writer=#writer#, hits=#hits#, regdate=#regdate#

                    where bbsno=#bbsno#

             ]]>

       </update>

      

       <delete id="deleteBBS" parameterClass="java.lang.Integer">

             <![CDATA[

                    DELETE FROM TBL_BBS WHERE bbsno=#bbsno#

             ]]>

       </delete>

      

</sqlMap>

SQL문이 기술되어 있습니다여기서 중요한 것이 ParameterClass resultClass입니다이는 Ibatis에서 SqlMapClient에서 매개변수로 넘기는 데이터 형태를 말합니다여기서 #bbsno#등과 같이 ## 묶여있는 것은 Ibatis에서 자동으로

맵핑을 시켜줍니다 SELECT문의 #bbsno# getBbsno() 메소드와 맵핑을 시킵니다그러므로 해당 필드들은 대소문자를 구분합니다.

 

 그럼 BbsDAOImpl 클래스를 한번 만들어보겠습니다.

package org.power.dao;

 

import org.power.vo.BbsVO;

 

public class BbsDAOImpl extends AbstractIbatis implements BbsDAO {

 

       @Override

       public void insert(BbsVO vo) throws Exception {

             sqlMapper.insert("insertBBS", vo);           

       }

 

       @Override

       public BbsVO select(int bbsno) throws Exception {

            

             return (BbsVO) sqlMapper.queryForObject("selectBBS", bbsno);

       }

 

       @Override

       public void update(BbsVO vo) throws Exception {

             sqlMapper.update("updateBBS", vo);

       }

 

       @Override

       public void delete(int bbsno) throws Exception {

             sqlMapper.delete("deleteBBS",bbsno);

            

       }

}

 

자 그럼 Junit을 통해 단위테스트를 해보겠습니다해당 코드는 아래와 기존과 동일합니다.

package org.power.test;

 

import org.power.dao.BbsDAO;

import org.power.dao.BbsDAOImpl;

import org.power.vo.BbsVO;

 

import junit.framework.TestCase;

 

public class BbsDAOTest extends TestCase {

 

       private BbsDAO bbsDao;

 

       protected void setUp() throws Exception {

             super.setUp();

 

             bbsDao = new BbsDAOImpl();

 

       }

 

       public void testInsert() {

 

 

             BbsVO vo = new BbsVO();

 

             try {

 

                    vo.setTitle("Ibatis사용 새로운 글을 등록합니다.(타이틀)");

                    vo.setContent("Ibatis사용  새로운 글을 내용을합니다.");

                    vo.setHits(100);

                    vo.setWriter("S002");

 

                    bbsDao.insert(vo);

 

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

 

       }

 

       public void testSelect() {

 

             BbsVO vo = new BbsVO();

 

             try {

                    vo = bbsDao.select(200);

 

                    System.out.println(vo.getBbsno());

                    System.out.println(vo.getTitle());

                    System.out.println(vo.getContent());

                    System.out.println(vo.getWriter());

                    System.out.println(vo.getRegdate());

 

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

 

       }

 

       public void testUpdate() {

 

             BbsVO vo = new BbsVO();

 

             try {

 

                    vo = bbsDao.select(300);

 

                    vo.setTitle("300  타이틀 수정입니다.");

                    vo.setContent("300  내용 수정한 내용입니다");

                    vo.setHits(0);

                    bbsDao.update(vo);

             catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

       }

 

       public void testDelete() {

 

             try {

                    bbsDao.delete(150);

              catch (Exception e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             }

       }

}

 

testInsert() 테스트 결과

testSelect() 테스트 결과

 

Ibatis를 테스트 할 경우 하나의 메소드만 테스트를 하여도 전체 xml을 테스트하므로 에러메시지를 확인하여야 합니다.

 

자 기존의 소스와 비교하였을 때 매우 간단하게 구현하는 것을 볼 수 있으며 보다 확장성이 좋아진 것을 볼 수 있습니다.

, SQL을 수정 또는 추가시 기존 소스를 수정해야 하는 부분이 많이 줄어 들었으며 결과를 return하는 것도 ibatis에서 자동으로 설정하여 반환하므로 개발자는 거의 신경을 안써도 됩니다.

 

그런데 만약에 여러게의 게시판이 있다고 생각해봅시다각 게시판마다 이런 동일한 코드를 작성해야 할 까요.

다음번에는 좀 더 확장성이 좋게 VO, DAO를 설계해 보도록 해보겠습니다.

[출처] http://blog.naver.com/byebird

'Programming > Java' 카테고리의 다른 글

Generic을 사용한 VO, DAO의 구현  (0) 2011.07.19
JDBC를 이용한 VO,DAO의 구현  (0) 2011.07.19
Posted by 그리브스
, |

JDBC를 사용하여 Oracle 데이터를 Connection하는 doa, vo를 설계해 보자.

 

1. 테스트를 위한 간단한 게시판테이블을 생성해 보자.


CREATE TABLE TBL_BBS

(

             bbsno                NUMBER(15)  NOT NULL ,

             title                 VARCHAR2(200)  NULL ,

             writer                VARCHAR2(20)  NULL ,

             hits                  NUMBER(5)  NULL ,

             content               VARCHAR2(500)  NULL ,

             regdate               DATE  DEFAULT sysdate

);

 

2. Sequece도 생성해 줍니다.

CREATE SEQUENCE seq_bbsno;

 

3. 테스트 데이터를 입력합니다.

INSERT INTO tbl_bbs (bbsno, title, content, writer, hits)

VALUES(SEQ_BBSNO.NEXTVAL,'jdbc 테스트를 위한 Sample data 입니다.', 'sample data contents 입니다.','S0001',0);

 

데이터는 많을수록 좋죠 ^^; 몇건을 더 넣어 보겠습니다. ( 아래 쿼리를 실행시키면 금방 수만건의 데이터를 만들수 있겠죠 ^^)

INSERT INTO tbl_bbs (bbsno, title, content, writer, hits)(SELECT SEQ_BBSNO.NEXTVAL, title, content, writer, hits FROM TBL_BBS);

 

글내용이 동일하니 구분을 주기 위해서 시퀀스 번호를 타이틀과 내용에 추가해 보겠습니다.

UPDATE TBL_BBS SET TITLE = TITLE || '(' || BBSNO || ')',CONTENT = CONTENT || '(' || BBSNO || ')'

 

조회해 보면 아래와 같은 데이터가 생성된 되겠죠 ^^;

 

자 우선 VO(Value Object)를 만들어야 겠죠?

package org.power.vo;

 

import java.util.Date;

public class BbsVO {

            

             private int bbsno;

             private String title;

             private String writer;

             private int hits;

             private String content;

             private Date regdate;

            

             public int getBbsno() {

                           return bbsno;

             }

             public void setBbsno(int bbsno) {

                           this.bbsno = bbsno;

             }

             public String getTitle() {

                           return title;

             }

             public void setTitle(String title) {

                           this.title = title;

             }

             public String getWriter() {

                           return writer;

             }

             public void setWriter(String writer) {

                           this.writer = writer;

             }

             public int getHits() {

                           return hits;

             }

             public void setHits(int hits) {

                           this.hits = hits;

             }

             public String getContent() {

                           return content;

             }

             public void setContent(String content) {

                           this.content = content;

             }

             public Date getRegdate() {

                           return regdate;

             }

             public void setRegdate(Date regdate) {

                           this.regdate = regdate;

             }

}

 

 

Interface를 설계합니다.

package org.power.dao;

 

import org.power.vo.BbsVO;

 

public interface BbsDAO {

            

             public void insert(BbsVO vo) throws Exception;

             public void select(int bbsno) throws Exception;

             public void update(BbsVO vo) throws Exception;

             public void delete(int bbsno) throws Exception;

            

}

 

AbstractDAO를 설계합니다바로 BbsVO Implements해도 되지만 JDBC에서 connection, closing과 같은 일련의 작업을 Abstract 클래에서 처리함으로써 프로그램을 단순화하고 재사용성과 안정성을 높입니다.

package org.power.dao;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

 

public abstract class AbstractDAO{

 

             Connection con;

             PreparedStatement pstmt;

             ResultSet rs;

            

             public final void execute() {

                          

                           try {

                                        init();

                                        query();

                                        close();

                           catch (Exception ex) {

                                        ex.printStackTrace();

                           }

             }

            

             private void init() throws Exception {

                           Class.forName("oracle.jdbc.driver.OracleDriver");

                           con = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:ORCL""tony""1234");

 

             }

             public abstract void query() throws Exception;

             private void close() {

 

                           if(rs != null)try {rs.close();} catch (Exception e) {}

                           if(pstmt != null)try {rs.close();} catch (Exception e) {}

                           if(con != null)try {rs.close();} catch (Exception e) {}

             }

}

 

BbsDAOImpl의 최종결과는 아래와 같습니다위의 AbstractDAO와 같은 패턴으로 설계를 한 경우 개발자는 단순히 아래와 같이 Query부분만 신경쓰면 되므로 생산성과 프로그램의 안정성이 더욱 좋아 질 것입니다.

package org.power.dao;

 

import org.power.vo.BbsVO;

 

public class BbsDAOImpl implements BbsDAO {

            

             final StringBuffer sql = new StringBuffer();

             final BbsVO bbsvo = new BbsVO();

            

             public void insert(final BbsVO vo) throws Exception {

                          

                           sql.append(" INSERT INTO TBL_BBS ");

                           sql.append(" (bbsno, title, content, writer, hits) ");

                           sql.append(" VALUES (?, ?, ?, ?, ?)");

                          

                           new AbstractDAO() {

                                       

                                        public void query() throws Exception {

                                                    

                                                     pstmt = con.prepareStatement(sql.toString());

                                                     pstmt.setInt(1, vo.getBbsno());

                                                     pstmt.setString(2, vo.getTitle());

                                                     pstmt.setString(3, vo.getContent());

                                                     pstmt.setString(4, vo.getWriter());

                                                     pstmt.setInt(5, vo.getHits());

                                                     pstmt.executeQuery();

                                                    

                                        }

                           }.execute();

             }

 

             @Override

             public BbsVO select(final int bbsno) throws Exception {

                          

                           sql.append(" SELECT ");

                           sql.append(" bbsno, title, content, writer, hits, regdate ");

                           sql.append(" FROM TBL_BBS WHERE bbsno = ? ");

                          

                           new AbstractDAO() {

                                       

                                        public void query() throws Exception {

                                                    

                                                     pstmt = con.prepareStatement(sql.toString());

                                                     pstmt.setInt(1, bbsno);

                                                     rs = pstmt.executeQuery();

                                                    

                                                     while(rs.next()) {

                                                                 

                                                                  bbsvo.setBbsno(rs.getInt(1));

                                                                  bbsvo.setTitle(rs.getString(2));

                                                                  bbsvo.setContent(rs.getString(3));

                                                                  bbsvo.setWriter(rs.getString(4));

                                                                  bbsvo.setHits(rs.getInt(5));

                                                                  bbsvo.setRegdate(rs.getDate(6));

                                                                 

                                                     }                                                                

                                        }

                           }.execute();

                          

                           return bbsvo;

             }

 

             @Override

             public void update(final BbsVO vo) throws Exception {

                          

                           sql.append(" UPDATE TBL_BBS SET ");

                           sql.append(" title=?, content=?, writer=?, hits=? ");

                           sql.append(" WHERE bbsno=? ");

                          

                           new AbstractDAO() {

                                       

                                        public void query() throws Exception {

                                                    

                                                     pstmt = con.prepareStatement(sql.toString());

                                                     pstmt.setString(1, vo.getTitle());

                                                     pstmt.setString(2, vo.getContent());

                                                     pstmt.setString(3, vo.getWriter());

                                                     pstmt.setInt(4, vo.getHits());

                                                     pstmt.setInt(5, vo.getBbsno());

 

                                                     pstmt.executeQuery();

                                                                                                                      

                                        }

                           }.execute();

 

             }

 

             @Override

             public void delete(final int bbsno) throws Exception {

 

                           sql.append(" DELETE FROM TBL_BBS ");

                           sql.append(" WHERE bbsno=? ");

                          

                           new AbstractDAO() {

                                       

                                        public void query() throws Exception {

                                                    

                                                     pstmt = con.prepareStatement(sql.toString());

                                                     pstmt.setInt(1, bbsno);

                                                     pstmt.executeQuery();

                                                                                                                      

                                        }

                           }.execute();                      

             }

}

 

 

위와 같이 한다 하더라도 많은 노가다성 코드가 존재하네요..;;; 나중에 ibatis라를 library를 사용하여 이런 부분을 해결하는 방안을 모색해 보겠습니다우선은 JDBC를 기준으로 작성을 해보겠습니다.

 

그럼 VO, DAO 설계를 마쳤습니다그럼 정상적으로 작동하는지 테스트를 해보겠습니다테스트는 Junit 툴을 사용하여 테스트를 해보겠습니다여기서는 Junit3.0을 기준으로 해보겠습니다.

  

Junit3.0 라이브러리가 세팅되었습니다이제 테스트 코드를 작성합니다.

 

Junit 테스트 클래스를 만들 때 setup stub메소드 부분을 체크해 주세요. Junit에서 테스트를 할 때 초기값 설정을 본 메소드에서 합니다.

 

자 테스트코드를 만들어 보겠습니다.

 

package org.power.test;

 

import org.power.dao.BbsDAO;

import org.power.dao.BbsDAOImpl;

import org.power.vo.BbsVO;

 

import junit.framework.TestCase;

 

public class testDAO extends TestCase {

 

             private BbsDAO bbsDao;

 

             protected void setUp() throws Exception {

                           super.setUp();

                           bbsDao = new BbsDAOImpl();

             }

 

             public void testInsert() {

 

                           BbsVO vo = new BbsVO();

 

                           try {

 

                                        vo.setTitle("새로운 글을 등록합니다.(타이틀)");

                                        vo.setContent("새로운 글을 내용을합니다.");

                                        vo.setHits(100);

                                        vo.setWriter("S002");

 

                                        bbsDao.insert(vo);

 

                           catch (Exception e) {

                                        // TODO Auto-generated catch block

                                        e.printStackTrace();

                           }

 

             }

 

             public void testSelect() {

 

                           BbsVO vo = new BbsVO();

 

                           try {

                                        vo = bbsDao.select(200);

 

                                        System.out.println(vo.getBbsno());

                                        System.out.println(vo.getTitle());

                                        System.out.println(vo.getContent());

                                        System.out.println(vo.getWriter());

                                        System.out.println(vo.getRegdate());

 

                           catch (Exception e) {

                                        // TODO Auto-generated catch block

                                        e.printStackTrace();

                           }

 

             }

 

             public void testUpdate() {

 

                           BbsVO vo = new BbsVO();

 

                           try {

 

                                        vo = bbsDao.select(300);

 

                                        vo.setTitle("300번 글 타이틀 수정입니다.");

                                        vo.setContent("300번 글 내용 수정한 내용입니다");

                                        vo.setHits(0);

 

                                        bbsDao.update(vo);

 

                           catch (Exception e) {

                                        // TODO Auto-generated catch block

                                        e.printStackTrace();

                           }

 

             }

 

             public void testDelete() {

 

                           try {

 

                                        bbsDao.delete(150);

 

                           catch (Exception e) {

                                        // TODO Auto-generated catch block

                                        e.printStackTrace();

                           }

 

             }

 

}

 

 

테스트코드를 작성하였습니다해당 메소드를 드래그하여 선택하고 실행하여 정상작동 여부를 확인할 수 있습니다. 

 

자 이제 DAO가 정상적으로 테스트 되는 것을 확인하였습니다. 이후 과정은 DAO를 사용하는 즉, business로직을 구현하는 Service를 설계해야겠지요. 서비스를 설계하고 구현한 다음 Web에서 들어오는 요청을 받아들이는 Servlet Controller를 설계 해야 됩니다. 대부분 이 부분은 Spring, Struts 등의 Servlet 프레임워크가 대체하고 있지요.

기본 적으로 웹을 작성할 때는 이와 같은 과정을 거치는 것 같습니다. VO, DAO, SERVICE까지를 Model라고 보고 Servlet Controller부분을 Controller로 봅니다. 그리고 JSP 또는 웹화면을 그리는 부분이 View단이라고 보면 됩니다.

이러면 MVC모델이 완성되는 군요. 우선은 JDBC를 사용하여 VO, DAO 설계 패턴을 만들어 보는데 목적이 있었으므로 목표는 완성했습니다.

그러나 위의 JDBC를 사용하여 하다 보니 애로사항이 발생합니다. 즉 각 DAO메소드를 구현할 때 엄청난 양의 코딩을 하게 되는군요. 생산성이 너무 떨어지게 되겠죠?? 다음에는 이를 해결하기 위해 ibatis를 활하여 만들어 보겠습니다.


[출처] http://blog.naver.com/byebird 

'Programming > Java' 카테고리의 다른 글

Generic을 사용한 VO, DAO의 구현  (0) 2011.07.19
Ibatis 라이브러리를 이용한 VO,DAO의 구현  (0) 2011.07.19
Posted by 그리브스
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함