캠핑과 개발

Eclipse plug-in

DEVELOPMENT/IDE2008. 12. 6. 13:15
1. Subversion : http://subclipse.tigris.org/update_1.2.x
2. Maven2 : http://m2eclipse.codehaus.org/update-dev/
3. Log4E : http://log4e.jayefem.de/update
4. Spring IDE : http://springide.org/updatesite/
5. DBViewer(DB쿼리툴) : http://www.ne.jp/asahi/zigen/home/plugin/dbviewer/
6. EclEmma(코드 커버리지 툴) : http://update.eclemma.org/
7. Implementor : http://eclipse-tools.sourceforge.net/updates/ 



#tip
weblogig plug-in 
   
http://download.oracle.com/otn_software/oepe/ganymede
    http://download.oracle.com/otn_software/oepe/galileo

 

'DEVELOPMENT > IDE' 카테고리의 다른 글

eclipse copy & Paste 느린 현상  (0) 2015.04.02
eclipse.ini 설정  (0) 2014.04.22
eclipse workspace 바로가기 링크 만들기  (0) 2010.11.17
Eclipse 유용한 PLUG-IN  (0) 2009.10.24
[eclipse] 자주쓰는 이클립스 단축키  (0) 2008.12.24

비밀번호가 틀렸습니다. 다시입력해주세요. => Invalid password. Please try again.
아이디가 틀렸습니다. 다시입력해주세요. => Invalid ID. Please try again.
제목을 입력하세요. Enter your subject(title).
제목을 입력하세요. Enter your contents(message).
이름을 입력해주세요. => Enter your name.
아이디를 입력하세요. Enter your ID.
패스워드를 입력하세요. Enter your password.
아이디가 존재하지 않습니다. 관리자에게 문의해 주세요. ID does not exist. Please contact the administrator.
접근 권한이 없습니다. IT실 담당자에게 문의하세요. Not permitted to log in/connect. Please contact the IT administrator.
접근권한이 없습니다. 관리자에게 문의해 주세요. Not permitted to log in/connect. Please contact the administrator.
파일을 삭제하시겠습니까? Delete? 파일이 정상적으로 삭제 되었습니다. Deleted successfully. (Files deleted successfully.)
등록 되었습니다. Registered/Saved successfully.
수정 되었습니다. Updated successfully.
삭제 되었습니다. Deleted successfully.
삭제할 데이터가 없습니다. Nothing to delete.
등록된 게시물이 없습니다. (게시물 = comment ?) No comment to delete.
검색할 성명을 입력하세요. Enter name to search for.
수신처를 지정해 주새요! Select contact method.
부서 이하를 선택해 주세요. Select department from the list.
검색된 사용자가 없습니다. Username does not exist.
메세지를 받을 사람을 입력해 주십시오. Enter recipient's name.

'DEVELOPMENT > Javascript' 카테고리의 다른 글

[HTML] 제어 문자  (0) 2009.01.16
[HTML 팁] HTML 소스 정렬 사이트  (0) 2008.12.27
javascript 디버거 툴  (0) 2008.08.18
클립보드 복사  (0) 2008.08.18
[javascript] dday 구하는 스크립트  (0) 2008.02.04

자바스크립트 디버거 툴
내일 당장 사용해보자~
사용자 삽입 이미지

익스플로어에서만 가능한 클립보드 복사하기다.

<script language="javascript">
    function setClipBoard(content){
        content +=  content + " [diem 블로그]";
        window.clipboardData.setData('Text', content);
        alert('내용이 복사되었습니다.');
    }
</script>

<a href="javascript:setClipBoard('http://hmjkor.tistory.com/')">복사하기</a>

테이블 관련 정보를 알아볼수 있는 쿼리를 정리했다.
나름 유용하게 사용할수 있을꺼 같다.

# 해당 테이블스페이스에 관련된 모든 테이블을 가져온다.
SELECT * FROM TABS

# 해당 테이블스페이스에 관련된 모든 시퀀스를 가져온다.
SELECT * FROM SEQ

# 해당 테이블스페이스에 관련된 모든 뷰의 정보를 가져온다.
SELECT * FROM USER_VIEWS

# 해당 테이블에 컬럼리스트를 가져온다.
SELECT *
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = 테이블명
ORDER BY COLUMN_ID ASC

# 해당 테이블스페이스에 관련된 모든 트리거를 가져온단.
SELECT * FROM USER_TRIGGERS

# 해당 테이블에 관련된 제약 정보들을 가져온다.
SELECT  C.TABLE_NAME A1,
        SUBSTR(A.COLUMN_NAME,1,15) A2,
        DECODE(B.CONSTRAINT_TYPE, 'P','PRIMARY KEY',
                                  'U','UNIQUE KEY',
                                  'C','CHECK OR NOT NULL',
                                  'R','FOREIGN KEY') A3,
        A.CONSTRAINT_NAME   A4      
FROM    USER_CONS_COLUMNS  A,  USER_CONSTRAINTS  B, USER_INDEXES C
WHERE   A.TABLE_NAME = B.TABLE_NAME
AND     A.TABLE_NAME = C.TABLE_NAME
AND     A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
AND     A.TABLE_NAME =UPPER('테이블명')

ORDER BY 1,2;

'DEVELOPMENT > Database' 카테고리의 다른 글

oracle 시작과 종료  (0) 2009.05.07
Toad 단축키  (0) 2009.04.18
[oracle] decode 함수  (1) 2009.01.16
[MS-SQL] SELECT INTO  (0) 2008.05.20
[oracle] 오라클 중복제거 하면서 전체 값 가져오기  (0) 2008.03.27

MD5 관련 함수

3주 동안 고인물로 지내다가 다시 새로운 물을 가득 넣기로 마음 굳게 먹었다.
요즘 별다르게 배운게 없고 공부한게 없었는데 이게 다 모 사이트 운영때문이다.. 결국은 핑계다 ㅡ,.-^

운영업무를 하다보면 고객의 요청에 의해서 각종 데이터들을 산출해야 한다.
회원정보라던지 매출액등 월말, 분기별로 아주 바쁘게 데이터를 뽑아서 엑셀로 이쁘게 포장해서
고객에게 주면 참 좋아 하신다..^^;

그런데 이런 데이터들을 산출하다 보면 SELECT 된 값들을 다른 테이블에 그 데이터만을 담아서 사용하고 싶은 경우가 있다. 그 중에 또 다른 값을 가져오거나  그 값들로 인해서 또 다른 테이블과 조인을 한다던가 해야 하는 일 말이다.  이런 테이블을 만들지 않으면 쿼리도 늘어나고 속도도 느려지니 헷갈리고 속도도 느려진다.

그래서 이 때  사용할수 있는게 SELECT INTO 이다.
SELECT INTO는 현재 있는 테이블에 있는 내용 전체나 일부를 가져와서 새로운 테이블로 만들 때 사용한다.
기존에 있던 테이블에는 INSERT 시킬수가 없다. 기존 테이블에 INSERT를 시킬려면 SELECT INSERT를 사용하면 된다.

사용법
SELECT * FROM tableName
SELECT * INTO  temp_tableName(새로만들 테이블) FROM tableName

위에 사용법으로 테이블을 만들게 되면 영구적으로 테이블이 생기게 된다.
물론 DROP 명령으로 지워주면 되긴 하지만 잠시만 쓰고 지울 것이라면 굳이 영구 테이블을 만들지 않고 임시테이블을 만들어 사용하면 된다.

임시 테이블은 전역임시 테이블, 세션 임시 테이블 두개로 나뉜다.

만드는방법 사용할 수 있는 범위 삭제되는 시기
일반 테이블 CREATE TABLE 다른 세션에서도 DROP TABLE
세션 임시 테이블
#tablename
해당 세션에서만
세션이 끊어질 때
전역 임시 테이블
##tablename
다른 세션에서도
세션이 끊어질 때
tempdb의 일반 테이블
CREATE TABLE
다른 세션에서도
SQL 서버가 시작 될 때

사용법
SELECT * INTO #tablename FROM table
SELECT * INTO ##tablename FROM table
SELECT * FROM #tablename
SELECT * FROM ##tablename

이렇게 생성 된 테이블은 해당 데이터베이스에 생성되는 것이 아니라 tempdb에 만들어 지며 logout 할 때 자동으로 삭제가 된다.

실무에서는 많이 사용하는지는 모르지만 개인적으로는 정말 많이 사용한다.

참고::
오라클에서는 사용법이 다르다.

CREATE TABLE tableName_temp
AS SELECT * FROM tableName


'DEVELOPMENT > Database' 카테고리의 다른 글

oracle 시작과 종료  (0) 2009.05.07
Toad 단축키  (0) 2009.04.18
[oracle] decode 함수  (1) 2009.01.16
[ORACLE] 테이블 관련 정보 쿼리  (0) 2008.07.26
[oracle] 오라클 중복제거 하면서 전체 값 가져오기  (0) 2008.03.27

쿠키는 웹 어플리케이션에서 클라이언트의 정보를 임시로 저장하기 위해 많이 사용된다. 또한, 클라이언트의 상태를 유지할 때 사용되는 세션을 구현하기 위해 쿠키를 사용하기도 한다. 쿠키를 사용함으로써 좀더 쉽고 간결한 방법으로 웹 어플리케이션을 구현할 수 있게 되는 경우가 많은데 이를 좀더 편하게 관리하기 위해서는 쿠기를 사용할 수 있는 보조 클래스를 만들어서 사용하게 되면 편리하다.

CookieBox.java

/*
 * @(#)CookieBox.java
 * Copyright (c) 2000~ NowOnPlay.com inc., All rights reserved.
 * Total E-Business Group, http://www.nowonplay.com
 *
 * 최초작성일자 : April 15, 2008 (hmjkor@nowonplay.com)
 * 수정이력 :
 */
package kevin.common.utils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Cookie;

import java.util.HashMap;
import java.util.Map;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.io.IOException;

/**
 * 쿠기를 보다 관리하기 쉽도록 만든 클래스로서
 * http://javacan.madvirus.net/에 있는 내용을 토대로 작성되었다.
 * @author diem
 *
 */
public class CookieBox {
   
    /* 쿠기를 담기위한 맵 */
    private Map cookieMap = new HashMap();
   
    /**
     * 생성자
     * request로 받은 쿠키값을 Key, value 값으로 매핑한다.
     * @param request
     */
    public CookieBox(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (int i = 0 ; i < cookies.length ; i++) {
                cookieMap.put(cookies[i].getName(), cookies[i]);
            }
        }
    }
   
    /**
     * 쿠키를 저장한다.
     * @param name 이름
     * @param value 값
     * @return
     * @throws IOException
     */
    public static Cookie createCookie(String name, String value)
    throws IOException {
        return new Cookie(name, URLEncoder.encode(value, "euc-kr"));
    }
   
    /**
     * 쿠키를 저장한다.
     * @param name 이름
     * @param value 값
     * @param path 경로
     * @param maxAge 유효시간
     * @return
     * @throws IOException
     */

    public static Cookie createCookie(
            String name, String value, String path, int maxAge)
    throws IOException {
        Cookie cookie = new Cookie(name,
                                URLEncoder.encode(value, "euc-kr"));
        cookie.setPath(path);
        cookie.setMaxAge(maxAge);
        return cookie;
    }
   
    /**
     * 쿠키를 저장한다.
     * @param name 이름
     * @param value 값
     * @param domain 도메인
     * @param path 경로
     * @param maxAge 유효시간
     * @return
     * @throws IOException
     */
    public static Cookie createCookie(
            String name, String value, 
            String domain, String path, int maxAge)
    throws IOException {
        Cookie cookie = new Cookie(name,
                  URLEncoder.encode(value, "euc-kr"));
        cookie.setDomain(domain);
        cookie.setPath(path);
        cookie.setMaxAge(maxAge);
        return cookie;
    }
   
    /**
     * 해당되는 쿠키를 가져온다.
     * @param name
     * @return 쿠키값
     */
    public Cookie getCookie(String name) {
        return (Cookie)cookieMap.get(name);
    }
   
    /**
     * 요청한 쿠키 이름의 값을 가져온다.
     * 가져온 값이 없을 경우 null을 리턴한다.
     * @param name 쿠키 이름
     * @return
     * @throws IOException
     */
    public String getValue(String name) throws IOException {
        Cookie cookie = (Cookie)cookieMap.get(name);
        if (cookie == null) return null;
        return URLDecoder.decode(cookie.getValue(), "euc-kr");
    }
   
    /**
     * 요청한 쿠기값이 있는지의 여부를 가져온다.
     * @param name 요청할 쿠키값
     * @return
     */
    public boolean exists(String name) {
        return cookieMap.get(name) != null;
    }
}

소스를 간단하게 설명을 하면 쿠기를 담는 맵을 생성 한 후  그 맵에 Key, Value 값으로 담아두고 Key에 해당하는 쿠기를 가져오는 클래스이다.

이를 사용하기 위해서는 다음과 같이 사용하면 된다.
// CookieBox 클래스의 생성자는 request로부터 쿠키 정보를 추출
CookieBox cookieBox = new CookieBox(request);

// 쿠키가 존재하지 않으면 null 리턴
Cookie idCookie = cookieBox.getCookie("id");

// 지정한 이름의 쿠키가 존재하는지의 여부
if (cookieBox.exists("name")) { ... }

//지정한 이름의 쿠키가 존재하지 않으면 값으로 null 리턴
 String value = cookieBox.getValue("key");


이글은 최범균님의 홈페이지에서 참고한것 입니다.

오늘 공부한 패턴은 Iterator 패턴이다. Iterator패턴이란 사전적 의미로는 반복자이다.
책에 쓰인 정의로는 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공해준다라고 되어 있다.

쉬운 예로 게시판을 예로 들어보자. 게시물의 들어가는 모든 내용(제목, 작성자, 내용, 등록을 등.)을 Board라는 객체를 만들어서 한번에 담아서 사용한다고 가장을 한다고 하면 대충 Board.java 안에는 이런 코드가 들어갈 것이다.

Board.java
package hmj.pattern.Iterator;

public class Board {
   
    private String name;
    private String subject;
    private String contents;
    private String registeDate;
   
    public Board(){}
    public Board(String name, String subject, String contents, String registeDate){
        this.name = name;
        this.subject = subject;
        this.contents = contents;
        this.registeDate = registeDate;
    }
   
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getContents() {
        return contents;
    }
    public void setContents(String contents) {
        this.contents = contents;
    }
    public String getRegisteDate() {
        return registeDate;
    }
    public void setRegisteDate(String registeDate) {
        this.registeDate = registeDate;
    }   
}


일반적으로 게시판에 들어가는 내용은 저정도일리 없겠지만 Iterator 패턴을 설명하기에는 부족함이 없을꺼 같다. 다른 두사람이 각기 다른 게시판의 리스트를 불러오는 작업을 했다고 가정을 하자. 

A라는 사람은,
public ArrayList<Board> getList() throws Exception { /* 리스트를 불러오기 위한 로직 */ } 을 사용하고

또 다른 B라는 사람은,
public Board[] getList() throws Exception { /*  리스트를 불러오기 위한 로직 */ } 을 사용하였다.

이런식으로 넘겨 받은 객체들은 View페이지에서 각기 리턴형식이 다르기 때문에 서로 다른 형식으로 루프를 돌면서 객체를 꺼내와야 될것이다. 그안에 들어있는 객체는 똑같이 Board형식인 객체인데 말이다. 그리고 또 C가 나타나서 또 다른 방법으로 리스트 목록을 불러오는 메소드를 만든다면 또 다른 방법으로 그 객체를 가져와야 할것이다. 이런 방법은 정말 불편할것이다. 또한 코드 관리 및 확장도 어려울 것이다.

디자인 원칙중에는 "바뀌는 부분을 캡술화 하라" 라는 디자인 원칙이 있다.
위에 리스트 목록을 불러오기 위해서 각기 서로 다른 방법으로 Board 객체를 불러와서 리스트 페이지에 뿌려준다. 이렇게 서로 다른 방식으로 객체를 가져오는 부분을 캡술화를 할수 있을까?

Iterator iterator = NoticeBoardFacade.createIterator();
while(iterator.hasNext()){
    Board board = (Board)iterator.next();
}

이런식으로 Iterator라는 객체를 만들어서 사용하면 어떨까? 리스트 목록을 Iterator라는 객체에 담아서 Iterator 내부에서 ArrayList이건 Board[] 배열이건 캡술화 해서 가져오게 하면 되지 않을까? 된다.. 이게 바로 Iterator 패턴이다..

모르겠으면 일단 한번 해보면 될것 아닌가? 열번 듣는것보다 한번 소스를 보는게 낫고 직접 타이핑을 해보면 더욱 좋다. 내가 그런게 아니고 다들 그러더라.. ㅡㅡ;
소스 코드를 보기 전에 가장 먼저 알아야 할것은 Iterator라는 인터페이스에 의존한다는 점이다.

Iterator.java
/*
 * @(#)Iterator.java
 * Copyright (c) 2000~ NowOnPlay.com inc., All rights reserved.
 * Total E-Business Group, http://www.nowonplay.com
 *
 * 최초작성일자 : April 14, 2008 (hmjkor@nowonplay.com)
 * 수정이력 :
 */
package hmj.pattern.Iterator.Iterator;

public interface Iterator {   
    public boolean hasNext();
    public Object next();
}

일단 이렇게 인터페이를 만들어 두면 그 어떤 종류의 객체 컬렉션도 알맞게 구현하여 반복자를 구현 할 수가 있다.

그럼 Iterator 인터페이스를 구현한 클래스 또한 봐야 이해가 갈것이다. 그럼 보자

NoticeBoardIterator.java
/*
 * @(#)NoticeBoardIterator.java
 * Copyright (c) 2000~ NowOnPlay.com inc., All rights reserved.
 * Total E-Business Group, http://www.nowonplay.com
 *
 * 최초작성일자 : April 14, 2008 (hmjkor@nowonplay.com)
 * 수정이력 :
 */
package hmj.pattern.Iterator.board;

import hmj.pattern.Iterator.Board;
import hmj.pattern.Iterator.Iterator.Iterator;

public class NoticeBoardIterator implements Iterator {
    
    private Board[] boards;
    private int position = 0;
    
    /**
     * 생성자
     * @param boards
     */
    public NoticeBoardIterator(Board[] boards) {
        // TODO Auto-generated constructor stub
        this.boards = boards;
    }
    
    /**
     * 해당 배열에 다음 객체가 있는지 여부를 리턴한다.
     */
    public boolean hasNext() {
        // TODO Auto-generated method stub
        if(position >= boards.length || boards[position] == null){
            return false;
        }else{
            return true;
        }        
    }
    
    /**
     * 해당 포지션에 대한 객체를 가져오고 해당 위치에 해당하는 포지션을 다음 포지션으로
     * 이동 시키기 위해  1 더해준다.
     */
    public Object next() {
        // TODO Auto-generated method stub
        Board board = boards[position];
        position = position + 1;
        return board;
    }
}

코드가 그리 어렵지 않아서 자세하진 않지만 간단한 주석만 봐도 알수 있을것이다.
Iterator 인터페이를 구현하여 hasnext(), next() 메소드를 정의해줬다. hasnext()메소드는 Board[]배열에 현재 위치값에서 다음 값이 있는지를 나타내는 메소드이고, next() 메소드는 현재 포지션의 객체를 리턴하고 다음 객체를 얻기 위해 포지션을 1 증가 시키는 메소드이다.

그럼 NoticeBoardFacade 에서는  public Board[] getList() {  ..코드 ..} 이런식으로 넘겨줬던 코드를 Iterator에 맞게 다시 수정을 해야 할것이다. 다음과 같이 말이다.

public Iterator createIterator() {
    /* boards 객체를 가져오기 위한 코드 */
    return new NoticeBoardIterator(boards);
}

이런식으로 넘겨 받은 객체를 View 페이지에서는 간단하게

Iterator iterator = NoticeBoardFacade.createIterator();
while(iterator.hasNext()){
    Board board = (Board)iterator.next();
    board.getName();
    board.getSubject();
    .
    .
}

위와 같은 식으로 사용하면 된다. 이렇게 되면 사용자들은 내부에서는 어떻게 돌아가는지 알지 못해도 간단하게 사용 할 수가 있다. 이게 바로 Iterator 패턴인다.
내용은 그리 어렵지 않은데 설명은 무척이나 길게 한듯하다..ㅠㅠ
오늘도 패턴 하나를 알았다. 패턴 정말 재미있어진다.


SELECT *
FROM (
  SELECT 컬럼1, 컬럼2, 컬럼3,
               ROW_NUMBER() OVER( PARTITION BY 중복조회컬럼 ORDER BY 정렬컬럼 ) CNT
  FROM 테이블
  )
WHERE CNT > 1
RANK() OVER()
DENSE_RANK() OVER()

실무에 사용했던 예))

'DEVELOPMENT > Database' 카테고리의 다른 글

oracle 시작과 종료  (0) 2009.05.07
Toad 단축키  (0) 2009.04.18
[oracle] decode 함수  (1) 2009.01.16
[ORACLE] 테이블 관련 정보 쿼리  (0) 2008.07.26
[MS-SQL] SELECT INTO  (0) 2008.05.20