[JAVA] JFrame 닫을때 이벤트

[JAVA] JFrame 닫을때 이벤트

JFrame jframe = new JFrame();

jframe.addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    System.out.println(“사용자 명령으로 종료합니다.”);
    System.exit(0);
   }
  });

java 현재 날짜 알아내기

java 현재 날짜 알아내기

현재날짜시간

현재시간

private static String getTodayDateTime() {
  cal = Calendar.getInstance();
  StringBuffer today = new StringBuffer();
  today.append(String.format(“%04d”, cal.get(cal.YEAR)));
  today.append(String.format(“%02d”, cal.get(cal.MONTH) + 1));
  today.append(String.format(“%02d”, cal.get(cal.DAY_OF_MONTH)));
  
  today.append(” “);
  
  today.append(String.format(“%02d”, cal.get(cal.HOUR_OF_DAY)));
  today.append(String.format(“%02d”, cal.get(cal.MINUTE)));
  today.append(String.format(“%02d”, cal.get(cal.SECOND)));
  return today.toString();
 }

java 파일의 수정한날짜 알아내기

java 파일의 수정한날짜 알아내기

File file = new File(“경로”);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis( file.lastModified() );

———-

// 파일의 수정시간 알아내기
 public String getFileModifyDateTime(File f) {
  
  try {
   Calendar cal = Calendar.getInstance();
   cal.setTimeInMillis(f.lastModified());
   return getTodayDateTime(cal);
   
  } catch (Exception e) {
   e.printStackTrace();
   return “알 수 없는 날짜”;
  }
 }
 
 private String getTodayDateTime(Calendar cal) throws Exception {
  StringBuffer today = new StringBuffer();
  today.append(String.format(“%04d”, cal.get(cal.YEAR)));
  today.append(“-“);
  today.append(String.format(“%02d”, cal.get(cal.MONTH) + 1));
  today.append(“-“);
  today.append(String.format(“%02d”, cal.get(cal.DAY_OF_MONTH)));
  
  today.append(” “);
  
  today.append(String.format(“%02d”, cal.get(cal.HOUR_OF_DAY)));
  today.append(“:”);
  today.append(String.format(“%02d”, cal.get(cal.MINUTE)));
  today.append(“:”);
  today.append(String.format(“%02d”, cal.get(cal.SECOND)));
  return today.toString();
 }

[JAVA] 자바 아이피주소 가져오기, ipAddress 얻기

[JAVA] 자바 아이피주소 가져오기, ipAddress 얻기

윈도우나 리눅스 등 운영체제와 상관없이 잘 동작한다.

public String getIpAddress() throws NullPointerException, Exception {
    String ipAddress = “”;
    boolean isLoopBack = true;
        
    Enumeration<NetworkInterface> en = null;
    en = NetworkInterface.getNetworkInterfaces();
        
    while (en.hasMoreElements()) {
        NetworkInterface ni = en.nextElement();
        if (ni.isLoopback()) {
            continue;
        }
        
        Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
        while (inetAddresses.hasMoreElements()) {
            InetAddress ia = inetAddresses.nextElement();
            if (ia.getHostAddress() != null && ia.getHostAddress().indexOf(“.”) != -1) {
                ipAddress = ia.getHostAddress();
                isLoopBack = false;
                break;
            }
        }
        
        if (!isLoopBack) {
            break;
        }
    }
        
    return ipAddress;
}

64bit 컴퓨터에서 vba Private Declare코드 사용하기

64bit 컴퓨터에서 vba Private Declare코드 사용하기

64bit 컴퓨터에서는 Private Declare Function 이라는 텍스트가 빨간색으로 표시되는 오류가 있다.

이를 무시하고 강제로 실행하게 되면,

컴파일 오류입니다: 이 프로젝트의 코드를 업데이트해야 64비트 시스템에서 사용할 수 있습니다. Declare 문을 검토하고 업데이트한 다음 PtrSafe 특성으로 표시하십시오.

라는 에러가 발생한다.

– 문제해결

Declare 뒤에 PtrSafe 라는 문자열을 붙인다.

Private Declare Function => Private Declare Function PtrSafe

Private Declare Sub => Private Declare Sub PtrSafe

예를 들어,

 

Private Declare Function ShellExecute Lib “shell32.dll” ~ 이 에러가 날 경우

Private Declare PtrSafe Function ShellExecute Lib “shell32.dll” ~ 으로 수정할 것.

Public Declare Sub Sleep Lib “kernel32.dll” ~ 이 에러가 날 경우

Public Declare PtrSafe Sub Sleep Lib “kernel32.dll” ~ 으로 수정할 것.

jsp tomcat url-pattern (스프링 jsp 직접호출 방법)

jsp tomcat url-pattern (스프링 jsp 직접호출 방법)

url-pattern 은 web.xml 에 정의해도 되고, 서블릿 상단에서 어노테이션 방식으로 써도 된다. (@WebServlet(urlPatterns = {“/”}) 이렇게 쓴다. 여러 개 쓰려면 @WebServlet(urlPatterns = {“/aaa/*”, “/bbb/*”}) 처럼 쓰면 된다.)

골 때리는건 url-pattern 은 except(exclude)를 설정할 수 없다. match(include) 작동만 한다. 아주 골 때린다.

더구나 정규식도 먹히지 않는다. 정규식이 아니라, 아주 한정적인 와일드 카드만 먹힌다.

1. /로 시작하고 /* 로 끝나도록 쓰는 패스. (ex : /temppath/*)

2. *.확장자 : 확장자를 매칭한다. (ex : *.do)

3. / : 디폴트 서블릿이다.

4. 그 외 동치 매칭이다.

한 마디로 [a-z], \d{1-4} 이딴거 안된다. 아…

아무튼 “*.do” 보다는 “/” 이라고 쓰는 디폴트 서블릿으로 설정하는게 가장 낫다. (그래야 REST 방식의 깔끔한 주소가 될 수 있다) 이렇게 하면 jsp, jspx, html, htm, js, css 등을 제외하고는 서블릿으로 갈 것이다. web.xml 에 보면 기존 servlet-mappng 에 jsp, jspx 가 설정되어 있을 것이다. 때문에 jsp는 처리가 된다. html, htm, js, css 는 정적 파일이기 때문에 그대로 bypass한다.


참고) web.xml


    <!– The mapping for the default servlet –>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!– The mappings for the JSP servlet –>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>

        <url-pattern>*.htm</url-pattern>

        <url-pattern>*.html</url-pattern>
        <url-pattern>*.js</url-pattern>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>

javascript 윈도우 가운데 띄우기

javascript 윈도우 가운데 띄우기

var winTop = -1;
 var winLeft = -1;
 var winWidth = 500;
 var winHeight = 500;
 
 if (winWidth < 1) {
  winWidth = 500;
 }
 if (winHeight < 1) {
  winHeight = 500;
 }
 
 if (winTop < 0) {
  winTop = Math.ceil((window.screen.height – winHeight)/2);
 }
 if (winLeft < 0) {
  winLeft = Math.ceil((window.screen.width – winWidth)/2);
 }
 
 var requestUrl = “타겟파일주소.jsp”;
 
 var sizeSpec = “top=” + winTop + “,left=” + winLeft + “,width=” + winWidth + “,height=” + winHeight;
 var etcSpec = “location=no,titlebar=no,scrollbars=no,toolbar=no,status=no,menubar=no,resizable=no”;
 
 window.open(requestUrl, “_blank”, sizeSpec + “,” + etcSpec);

[Eclipse] 이클립스 Ctrl+Shift+F 단축키로 포맷팅

[Eclipse] 이클립스 Ctrl+Shift+F 단축키로 포맷팅

​이클립스에서 단축키 Ctrl + I 를 누르면 자동으로 들여쓰기가 정렬되고
Ctrl + Shift + F 를 누르면 포맷팅이 된다.

포맷팅 방식이 마음에 들지 않는다면,
이클립스 상단 메뉴의 WIndow – Preferences – (좌측 리스트의) Java – Code Style – Formatter
에서 수정 가능하다.

New 버튼을 눌러 새로운 포맷팅을 만들 수 있다.

개인적으로 포맷팅만 하면 소스가 줄 바꿈 되어 엉망이 되는 것이 불만이었다.

1. 상단 탭의 Line Wrapping – Maximum line width 를 8000 으로 조정.
2. 상단 탭의 Comments – Maximum line width for comments 를 8000 으로 조정.

이제 줄 바뀜은 일어나지 않을 것이다.

함수/메서드, 클래스/인스턴스, 웹서버/와스, 추상 클래스/일반 클래스/인터페이스

함수/메서드, 클래스/인스턴스, 웹서버/와스, 추상 클래스/일반 클래스/인터페이스

1. 함수와 메서드의 차이

함수는 객체와 관련이 없는 함수다. 메서드는 객체에 속해있는 함수다.

그래서 자바는 메서드 라고 하고, 자바스크립트나 베이직같은 스크립트 언어에서는 함수라고 한다.

(물론 자바스크립트에서도 객체와 메서드를 만들 수 있다.)

2. 클래스와 인스턴스의 차이

클래스는 객체의 설계도이고, 인스턴스는 메모리 할당된(new 처리한) 객체다.

1개의 클래스를 토대로 n개의 인스턴스가 만들어질 수 있음.

3. 웹서버와 와스의 차이

웹서버는 정적 파일(html, 이미지, js)을 그대로 전달 해주고,

와스는 동적 파일(jsp)을 컴파일 처리한다.

웹서버의 대표적인 예로 아파치가 있고, 와스의 대표적인 예로 톰캣이 있다.

jsp 프로젝트를 실행할 때 톰캣으로 돌릴 수도 있고 아파치 + 톰캣으로 돌릴 수도 있는데,

둘 다 똑같이 돌지만 성능에 차이가 있다.

전자는 아파치가 html, 이미지, js를 처리하고 톰캣이 jsp를 처리한다.

후자는 톰캣 혼자 html, 이미지, js, jsp를 처리하니까 살짝 더 느리겠지.

4. 추상 클래스와 일반 클래스의 차이

추상 클래스는 구현되지 않은 메서드(=추상 메서드)가 1개 이상 존재한다.

일반 클래스는 모든 메서드가 구현되어 있다.

5. 추상 클래스와 인터페이스의 차이

추상 클래스는 어디까지나 클래스다. 상속 가능하다.

추상 클래스는 구현되지 않은 메서드와 구현된 메서드가 같이 존재할 수 있다.

인터페이스는 구현되지 않은 메서드만 갖고 있다. 클래스가 아니므로 상속(익스텐즈)이 불가능하고, 대신, 구현(임플리먼트) 가능하다.

자바는 다중 상속이 지원되지 않는 한편 인터페이스를 지원한다. (다중 상속의 장점만을 취함)

인터넷 익스플로러 항상 새 세션으로 띄우기

인터넷 익스플로러 항상 새 세션으로 띄우기

개발 작업하다 보면 여러 아이디로 테스트를 동시에 해야할 때가 많은데, 이럴 때 세션 꼬이지 않게 새 세션 띄우기를 해야한다.

내가 원래 사용하던 방법은,

1. 익스플로러 상단 메뉴의 ‘파일(F)’ – ‘새 세션(I)’ 으로 창 띄우기.

이 방법은 기존의 띄워져 있는 창을 굳이 찾아야 한다는 점이 불편하다. 항상 익스플로러가 새 세션이라는 보장도 없다.

새로운 방법은,

1. 익터넷 익스플로러 바로가기 아이콘 위에서 마우스 우클릭 – 속성 – 바로가기 탭 – 대상(T) 인풋박스 부분 맨 뒤에 -nomerge 라고 써준다.

이 때 바로가기 아이콘마다 다르게 적용되므로 바탕화면 바로가기, 작업표시줄의 바로가기 등 일일히 기입해 넣어줘야 한다.

한 번만 해두면 앞으로 해당 바로가기로 실행되는 익스플로러는 항상 새 세션이니 좋다.

세션을 유지하고 싶을 때는 윈도우가 이미 떠있는 상태이므로, 메뉴 – 새 창, 메뉴 – 탭 복제를 쓰면 되고. (단축키 : Ctrl + N(새 창), Ctrl + K (탭 복제))

레지스트리 값을 변경하는 방식도 있는데 그냥 바로가기 뒤에 -nomerge 주는게 낫다.

이거하자고 레지스트리 값 변경할 것 까지야 없다고 본다.

[mysql] Error Code: 1175. You are using safe update mode

[mysql] Error Code: 1175. You are using safe update mode

mysql 에서 테이블을 삭제하려고 할 때(delete from 테이블명) 아래처럼 에러 발생.

Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
 To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect. 0.000 sec

SQL 에디터에서

SET SQL_SAFE_UPDATES=0; 을 쿼리 실행하면 된다.

배치(bat) 또는 쉘(sh) 실행하는 자바 코드 (190214 수정)

배치(bat) 또는 쉘(sh) 실행하는 자바 코드 (190214 수정)

실행되었을 때 터미널 창에 찍히는 값을 가져올 수 있다.

ProcessBuilder processBuilder = null;
Process process = null;

try {

    String osType = “window”;

    // String osType = “unix”;

    String filePath = “”;

    if (osType.toLowerCase().indexOf(“window”) > -1) {
        processBuilder = new ProcessBuilder(“CMD”, “/c”, filePath /* 배치 파일 경로 */);
    } else {
        processBuilder = new ProcessBuilder(“sh”,filePath /* 쉘 파일 경로 */);
    }

    processBuilder.redirectErrorStream(true);
    process = processBuilder.start();
     
    BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line = null;
     
    while ((line = br.readLine() ) != null) {

        System.out.println(line);

    }

} catch (Exception e) {

    e.printStackTrace();

}

예제로 bat 파일을 만들고 싶다면 아래와 같이 작성해서 bat확장자로 저장하면 된다.

@echo off

echo 첫 번째 라인
echo 두 번째 라인
echo next line
echo bye

JAVA LPAD (ex: 자리수만큼 좌측부터 숫자 채우기)

JAVA LPAD (ex: 자리수만큼 좌측부터 숫자 채우기)

lpad는 좌측부터 자리수만큼 숫자 채우기, rpad는 우측부터 자리수만큼 숫자 채우기하는 SQL 함수 이름이다.

해당 기능의 함수를 따로 만들어쓰는 편인데, 귀찮다면 내장되어 있는 String.format 함수를 쓰면 된다.

String.format(“%06d”, 999);

== > 000999 가 된다.

응용해서 쓰면 됨.

예제 (오늘 날짜 가져오기)

     cal = Calendar.getInstance();
     StringBuffer today = new StringBuffer();
     today.append(“#”);
     today.append(String.format(“%04d”, cal.get(cal.YEAR)));
     today.append(“/”);
     today.append(String.format(“%02d”, cal.get(cal.MONTH) + 1));
     today.append(“/”);
     today.append(String.format(“%02d”, cal.get(cal.DAY_OF_MONTH)));
     today.append(” “);
     today.append(String.format(“%02d”, cal.get(cal.HOUR_OF_DAY)));
     today.append(“:”);
     today.append(String.format(“%02d”, cal.get(cal.MINUTE)));
     today.append(“:”);
     today.append(String.format(“%02d”, cal.get(cal.SECOND)));
     today.append(lineSeperator);

C프로그램의 디컴파일

C프로그램의 디컴파일

C에 대해서는 아는 바가 없어서 상무님께 여쭤보고 간단하게 기록해둔다.

자바 클래스는 jd gui 등으로 디컴파일을 해서 열어볼 수 있는데, c는 그럴 수 없는지 궁금했다.

컴파일할 때 뒤에 -d 옵션을 주면 디버그를 할 수 있도록 컴파일된다.

만약 해당 옵션을 주지 않는거나, 일반적인 컴파일일 경우에는 해당 파일을 GDB 로 디버그하며 쫓아갈 수 있다. 컴파일된 파일이 관련된 링크의 어드레스 정보를 갖고 있기 때문이다.

상용 배포하는 프로그램이라면 이러한 디컴파일, 디버그가 안되기를 바랄 것이다. 그럴 때 컴파일된 파일에 스트립 명령을 주면 된다.

기존 컴파일된 파일의 바이너리가 상당히 큰데, 이렇게 스트립 명령을 주면 바이너리가 확 줄어든다. 링크 어드레스 정보를 지우기 때문이다.

과거에 mfc 프로그래밍을 할 때 mfc42.dll 이라는 파일이 필요했는데, mfc 내부 로직이 어떻게 돌아가나 궁금할 수가 있다. 그럴 때 mfc42d.dll 파일을 system32 폴더 밑에 갖다놓고 돌리면 로직을 쫓아갈 수 있었다. mfc42.dll 파일은 스트립된 파일이고, mfc42d파일은 디버그용으로 컴파일 시킨 파일이다.

오라클 힌트(oracle hint)

오라클 힌트(oracle hint)

오라클 힌트란?

 

1) 개요

힌트는 SQL 튜닝의 핵심부분으로 일종의 지시구문이다. SQL에 포함되어 쓰여져 Optimizer의 실행 계획을 원하는 대로 바꿀 수 있게 해준다. 오라클 Optiomizer라고 해서 항상 최선의 실행 계획을 수립할 수는 없으므로 테이블이나 인덱스의 잘못된 실행 계획을 개발자가 직접 바꿀 수 있도록 도와주는 것이다.

사용자는 특정 SQL 문장에서 어떤 인덱스가 선택도가 높은지에 대해 알고 있는데 이 경우 오라클 서버의 Optimizer에 의존하여 나온 실행 계획보다 훨씬 효율적인 실행계획을 사용자가 구사할 수 있다.

 

2) 사용법

힌트를 사용하여 아래와 같은 것들을 할 수 있다.

액세스 경로, 조인 순서, 병렬 및 직렬처리, Optiomizer의 목표(Goal)를 변경 가능

 

3) 형태

SQL 문장 내에 “/*+ 힌트내용 */”이 추가된다.

주의! 주석 표시에 더하기(+)가 있다.

예1)

SELECT /*+ index( idx_col_1 ) */

           name, age, hobby

FROM     member

예2)

INSERT /*+APPEND*/ INTO TEST00 …

예3)

INSERT /*+PARALLEL*/ INTO TEST00 …

INDEX ACCESS OPERATION 관련 HINT
HINT 내용 사용법
INDEX  INDEX를 순차적으로 스캔 INDEX(TABLE명, INDEX명)
INDEX_DESC INDEX를 역순으로 스캔 INDEX_DESC(TABLE명, INDEX명)
INDEX_FFS INDEX FAST FULL SCAN INDEX_FFS(TABLE명, INDEX명)
PARALLEL_INDEX INDEX PARALLEL SCAN PARALLEL_INDEX(TABLE명,INDEX명)
NOPARALLEL_INDEX INDEX PARALLEL SCAN 제한 NOPARALLEL_INDEX(TABLE명,INDEX명)
AND_EQUALS INDEX MERGE 수행 AND_EQUALS(INDEX_NAME, INDEX_NAME)
FULL FULL SCAN FULL(TALBE명)
JOIN ACCESS OPERATION 관련 HINT
HINT 내용 사용법
USE_NL NESTED LOOP JOIN USE_NL(TABLE1, TABLE2)
USE_MERGE SORT MERGE JOIN USE_MERGE(TABBLE1, TABLE2)
USE_HASH HASH JOIN USE_HASH(TABLE1, TABLE2)
HASH_AJ HASH ANTIJOIN HASH_AJ(TABLE1, TABLE2)
HASH_SJ HASH SEMIJOIN HASH_SJ(TABLE1, TABLE2)
NL_AJ NESTED LOOP ANTI JOIN NL_AJ(TABLE1, TABLE2)
NL_SJ NESTED LOOP SEMIJOIN NL_SJ(TABLE1, TABLE2)
MERGE_AJ SORT MERGE ANTIJOIN MERGE_AJ(TABLE1, TABLE2)
MERGE_SJ SORT MERGE SEMIJOIN MERGE_SJ(TABLE1, TABLE2)
JOIN시 DRIVING 순서 결정 HINT
HINT 내용
ORDERED FROM 절의 앞에서부터 DRIVING
DRIVING 해당 테이블을 먼저 DRIVING- driving(table)
기타 힌트
HINT 내용
append insert 시 direct loading
parallel select, insert 시 여러 개의 프로세스로 수행- parallel(table, 개수)
cache 데이터를 메모리에 caching
nocache 데이터를 메모리에 caching하지 않음
push_subq subquery를 먼저 수행
rewrite query rewrite 수행
norewrite query rewrite 를  수행 못함
use_concat in절을 concatenation access operation으로 수행
use_expand in절을 concatenation access operation으로 수행 못하게 함
merge view merging 수행
no_merge view merging 수행 못하게 함

출처 1 : http://blog.naver.com/youngram2/220639017128

​출처 2 : http://iclickyou.com/845

출처 3 : http://blog.naver.com/wideeyed/80036376623

인덱스(index)에 대한 메모

인덱스(index)에 대한 메모

(인덱스에 대해 잘 아시는 분은 댓글을 통해 지식을 공유해주시기 바랍니다. 모호한 부분에 대한 지적 부탁드립니다. 감사합니다.)

아직 초보 개발자라 잘은 모르겠지만 인덱스에 대해 아는 대로 메모해둔다.

인덱스는 사전의 색인이라고 번역한다. 말 그대로 뭔가를 더 빠르게 찾아주기 위한 역할을 하는데, 따라서 where 문과 order by 에 쓰이는 듯 하다.

먼저 Primary Key 는 인덱스를 주지 않아도 된다. PK는 이미 인덱스가 걸려있기 때문이다. 그러나 PK가 아니라면?

예를 들어서 user_id 라는, PK가 아닌 컬럼이 있다고 해보자. select * from table user_id = ‘admin’ 이런 식으로 가져오겠지. 이 때, 인덱스가 없다면 테이블의 모든 로우를 풀 서치 해야한다.

그런데 user_id 가 미리 정렬되어 있다면 어떨까? 첫 글자가 a인 구간만 돌고, b인 구간에 들어서면 반복문을 빠져나가면 된다. 내 생각엔 인덱스를 걸어두면, 해당 컬럼을 미리 정렬해두는 것 같다. 그리고 insert를 할 때 마다 정렬이 되면서 삽입되겠지.

그러니까 인덱스는 where 문에도 쓰이고, order by 에도 쓰이는 것 같다. 다른 곳에 또 쓰이는지는 아직 모르겠다.

어디에 또 쓰이는지는 아직 잘 모르겠다.

인덱스는 이런 식으로 만든다.

CREATE INDEX IDX_테이블명_인덱스명 ON 테이블명
(컬럼명)
NOLOGGING
NOPARALLEL;

목록 쿼리가 select * from table user_id = ‘admin’ 로 쓰이고 있다면 다음과 같이 만들면 되는 것 같다.

CREATE INDEX IDX_TABLE_USERID ON TABLE
(USER_ID)
NOLOGGING
NOPARALLEL;

이 때, 아래와 같이 정렬 기준을 줘도 된다.

CREATE INDEX IDX_테이블명_컬럼명 ON 테이블명
(컬럼명 DESC)
NOLOGGING
NOPARALLEL;

정렬 순서는 DESC 라고 명시하지 않으면, 기본값은 무조건 ASC로 들어가는 것 같다.

이렇게 인덱스에는 이미 정렬 순서가 있기 때문에, 해당 인덱스를 타면 ORDER BY 를 주지 않아도 기본적으로 정렬되어 출력된다고 한다. (USER_ID DESC) 로 쓴 경우에는 사용자 아이디 내림차순으로 돌겠지.

where 문에 컬럼 두 개가 들어간다면 아래와 같은 방식으로 쓴다. 

CREATE INDEX IDX_테이블명_인덱스명 ON 테이블명
(컬럼1 DESC, 컬럼2 ASC)
NOLOGGING
NOPARALLEL;

NOPARALLEL 말고 다른 건 없을까? PARALLEL 을 쓰면 된다. 기본값은 병렬 처리를 하지 않는 NOPARALLEL 이다. 병렬처리에 대해서는 아직 잘 모르겠다. 다만, 아래와 같은 식으로 쓰는걸 확인했다.

CREATE INDEX IDX_테이블명_인덱스명 ON 테이블명
(컬럼1 DESC, 컬럼2 ASC)
NOLOGGING

PARALLEL ( DEGREE 8 INSTANCES 1 );


이렇게 인덱스는 컬럼 1개 짜리, 2개 짜리, 3개 짜리 식으로 쓸 수 있기 때문에 (아직 4개 짜리는 보지 못했다.), 어떤 인덱스를 타냐에 따라서 효율이 달라진다. 그냥 select 를 하면 DB 옵티마이저가 인덱스를 자동으로 선택해주는 것으로 알고 있다. 이럴 때 여러 개의 인덱스 중 원하는 인덱스를 항상 타도록 만드는 문구가 힌트(Hint)다. 여러 줄 주석처럼 생겼지만(/* ~ */) 이게 힌트다.

select   /*+ index( idx_col_1 ) */

           name, age, hobby

from     member

인덱스는 사전의 색인처럼 검색과 정렬을 빠르게 해준다. 그렇기 때문에 값이 0 아니면 1이라던가, 중복된 값이 많은 컬럼에는 사용해봤자 별 소용이 없다. 밸류 하나하나가 유니크한 컬럼에 쓰면 효과가 좋다.

마지막으로 인덱스를 써도 느릴 경우는?

첫째, 전체 데이터 수가 별로 없다면 인덱스를 써서 오히려 느릴 수가 있다. 풀 스캔이 더 빠른데 괜시리 인덱스 영역을 건너갔다 오는 것이기 때문이다.

둘째, DB 마이그레이션(기존 시스템의 데이터를 새 시스템에 옮기는 일)을 여러 번 수행한 경우에 느릴 수 있다. 한 마디로 n개의 컬럼을 insert했다가, delete했다가, insert했다가, delete 했다가… 식으로 반복하면 인덱스에 가비지 값이 많이 쌓이면서 효율이 느려지는 것 같다. 이럴 때 인덱스를 리빌드(Rebuild)하면 다시 속도가 빨라진다.

2016년 11월 29일 화요일 흑곰 씀.

(초보 개발자입니다. 인덱스에 대해 잘 아시는 분은 댓글을 통해 지식을 공유해주시기 바랍니다. 모호한 부분에 대한 지적 부탁드립니다. 감사합니다.)

오라클 숫자 뒤의 알파벳 의미 (오라클 i, g, c의 의미)

오라클 숫자 뒤의 알파벳 의미 (오라클 i, g, c의 의미)

orcale 7 -> 8i -> 9i -> 10g -> 11g -> 12c

i : Internet의 약자. 응용프로그램 지원

g : Grid computing의 약자. 분산 네트워크를 통한 자원통합을 지원

c : Cloud computing의 약자. 데이터베이스 자체적으로 가상화를 지원

js 현재 브라우저가 IE(인터넷익스플로러)인지 확인하기

js 현재 브라우저가 IE(인터넷익스플로러)인지 확인하기

var agent = navigator.userAgent.toLowerCase();

if (agent.indexOf(“msie”) > -1 || agent.indexOf(“trident”) > -1) {

    // 익스플로러임

} else {

    // 익스플로러 아님

}

익스플로러 10까지는 msie 라는 단어가 들어있으면 익스플로러다.

11에도 적용이 되는데, 마이너 버전에 따라 msie 라는 단어가 들어가있지 않은 경우가 있나보다.

그럴 땐 trident 라는 단어로 찾으면 된다. trident 는 IE에서 쓰는 레이아웃 엔진의 이름이다.

크롬, 파이어폭스, 사파리를 찾으려면 각각 

agent.indexOf(“chrome”) > -1

agent.indexOf(“firefox”) >-1

agent.indexOf(“safari”) >-1

이런식으로 찾으면 되겠다.

근데 크롬은 userAgent에 safari라는 단어가 포함되어 있더라.

그러므로 크롬 체크를 사파리 체크보다 우선순위로 해둬야겠지.

나야 크롬인지 아닌지 체크할 일이 없으니 문제 없지만 해당되는 분들은 잘 확인해볼 것.

인스톨 파일(셋업 파일) 디지털 서명 넣는 법

인스톨 파일(셋업 파일) 디지털 서명 넣는 법

인터넷에서 파일을 다운받았는데, 이 프로그램의 서명이 손상되었거나 잘못되었습니다. 라고 나오는 경우가 있다.

프로그램의 사용자 입장이라면 다운받은 파일 위에서 1. 마우스 우클릭 – 2. 실행을 선택해서 실행하면 된다. 단, 이게 바이러스거나 랜섬웨어일 경우는 책임 못진다. 직접 만든 프로그램이 아니면 실행하지 않는걸 추천한다.


만약 프로그램의 제작자 입장이라면 디지털 서명을 입혀 보내야 한다.

완성된 install 파일(exe)에 서명을 입힐 수 있는 프로그램이 있다. signcode.exe 다.

1. 시작 – 실행 – signcode.exe 실행해서 하라는대로 진행하면 된다.

엑셀VBA 행높이 자동조절(Row AutoFit)

엑셀VBA 행높이 자동조절(Row AutoFit)

엑셀에서 row와 row 사이 경계선을 더블클릭하면 행높이가 자동조절된다. 명칭은 몰랐는데 이걸 AutoFit 기능이라고 하나보다.

vba에서 AutoFit을 실행하려면 아래와 같이 쓰면 된다.

‘1로우부터 5000로우까지 행높이 자동조절

Rows(“1:50000”).EntireRow.AutoFit 

자바 정규식 기본정리 : Matcher, Pattern, find(), group()

자바 정규식 기본정리 : Matcher, Pattern, find(), group()

정규식을 사용하면 문자열(String)이 특정 패턴과 일치하는지 여부를 확인하거나, 패턴에 맞는 값을 찾아내거나, 해당 값을 새로운 값으로 바꿀 수 있다.

이 방법이 일목요연하게 작성되어 있는 곳이 마땅히 보이지 않았기에 직접 정리해서 써본다.

1. matches (일치하는지 확인)

target 은 대상이 되는 문자열(문장)을 담는 변수이고, regEx는 정규식(Regular Expression) 을 담는 변수라고 해보자.

public void isEqualRegEx() {
    String target = “나는 2008년도에 입학했다.”;
    String regEx = “.*\\d{1}.*”;
    // String regEx = “.*[0-9].*”; 와 동일함
  
    if (target.matches(regEx)) {
        System.out.println(“일치”);
   
    } else {
        System.out.println(“불일치”);
    }
}

여기서 regEx 는 “.*\\d{1}.*”; 이다. 즉 여기서 target.matches(regEx) 는 숫자가 1개라도 포함되어 있느냐고 묻는 것이다.
(“.*” 는 모든 복수의 문자이고, “\\d{1}”는 한 자리 숫자이므로.)

이 경우 2008, 이렇게 숫자가 4개나 있으니까 당연히 “일치”가 출력되겠지.
만약 regEx 값이 바뀐다면 어떨까?

regEx == “.*\\d{1}.*”  -> 일치
regEx == “.*[0-9].*”  -> 일치 ([0-9]는 \\d{1} 와 정확히 같은 뜻임)

regEx == “.*[0-9][0-9][0-9][0-9].*” -> 일치 (숫자 4자리)
regEx == “.*[0-9][0-9][0-9][0-9][0-9].*” -> 불일치 (숫자 5자리)

regEx == “.*\\d{1,4}.*” -> 일치 (숫자 1자리 이상 4자리 이하)
regEx == “.*\\d{2,5}.*” -> 일치 (숫자 2자리 이상 5자리 이하)
regEx == “.*\\d{5,6}.*” -> 불일치 (숫자 5자리 이상 6자리 이하)

요런 식으로 되겠다.

2. replaceAll (패턴에 맞는 값을 새로운 값으로 치환)

public void replaceRegEx() {
    String target = “나는 2008년도에 입학했다.”;
    String regEx = “[0-9]”;
    Pattern pat = Pattern.compile(regEx);
  
    Matcher m = pat.matcher(target);
    String result = m.replaceAll(“2”); // 패턴과 일치할 경우 “2”로 변경
    
    System.out.println(“출력 : ” + result);
    // 출력 : 나는 2222년도에 입학했다.
}

여기서 regEx 변수 값은 “[0-9]” 이다. 그러니까 위 소스는 1자리 숫자들을 “2”로 치환하게 된다.
결과는 당연히 “나는 2222년도에 입학했다.”가 된다.

위 함수를 3줄로 줄이면 아래와 같다.

public void replaceRegEx() {
    String target = “나는 2008년도에 입학했다.”;
    String regEx = “[0-9]”;
    System.out.println(“출력 : ” + target.replaceAll(regEx, “2”));
}

String 객체에 replaceAll 라는 멤버함수가 있다. 이게 더 낫다.
전자는 Pattern 객체와 Matcher 객체를 추가로 임포트하는데, 후자는 String 객체만 있으면 되니까.

3-1. find(), group() (패턴에 맞는 값 1개씩 찾아내기)

요 find랑 group이라는 함수가 특이한데 Matcher 의 멤버함수다.
일단 단순무식한 코드로 배워보자.

public void findRegEx(){
    String target = “나는 2008년도에 입학했다.”;
    String regEx = “[0-9]”;


    // 정규식(regEx)을 패턴으로 만들고,
    Pattern pat = Pattern.compile(regEx);
    // 패턴을 타겟 스트링(target)과 매치시킨다.
    Matcher match = pat.matcher(target);


    System.out.println(match.find());  // true
    System.out.println(match.group()); // 2
    
    System.out.println(match.find());  // true
    System.out.println(match.group()); // 0
    
    System.out.println(match.find());  // true
    System.out.println(match.group()); // 0
    
    System.out.println(match.find());  // true
    System.out.println(match.group()); // 8
    
    System.out.println(match.find());  // false
    System.out.println(match.group()); // 에러 발생! (IllegalStateException)
}

Pattern에 compile로 정규식(regEx)을 담고, Matcher에 타겟 스트링(target)을 담는게 먼저다.

그 다음 Matcher의 find() 함수를 쓰면 1번째 값을 찾아내고, true 혹은 false를 반환한다.
group() 을 쓰면 방금 찾은 1번째 스트링이 튀어나온다.

다시 find()를 쓰면 2번째 값을 찾고, group()을 쓰면 2번째 값이 튀어나오고… 이런 식이다.

보면 2, 0, 0, 8 까지 잘 가다가 (숫자가 더 이상 없으므로 당연히) 5번째에서 에러가 나는데,
따라서 에러가 나지 않도록 코드를 쓴다면 아래와 같이 작성해야 마땅하겠다.

…(전략)…

    if (match.find()) {
        System.out.println(match.group());
    }

…(후략)…

3-2. find(), group() (패턴에 맞는 값 모두 찾아내기)
3-1에서 설명한 바를 잘 정리한게 아래 메서드다.

public void findAllRegEx(){
    String target = “나는 2008년도에 입학했다.”;
    String regEx = “[0-9]”;

    Pattern pat = Pattern.compile(regEx); 
    Matcher match = pat.matcher(target);
    
    int matchCount = 0;
    while (match.find()) {
        System.out.println(matchCount + ” : ” + match.group());
        matchCount++;
    }
    System.out.println(“총 개수 : ” + matchCount);
    
    // 0 : 2
    // 1 : 0
    // 2 : 0
    // 3 : 8
    // 총 개수 : 4
}

보시다시피 while문을 사용해 find()가 false가 될 때까지 루프를 돌리면 된다.

끝. bb_ 2016-11-16 18:03

 

[Eclipse] 이클립스에 자바 클래스 디컴파일러 설치하는 법

[Eclipse] 이클립스에 자바 클래스 디컴파일러 설치하는 법

기본적으로 확장자 Java파일은 메모장으로도 잘 열리지만 Class 파일은 컴파일된 상태라 열 수가 없다. 이럴 때 답답하다. “이거 안쪽이 어떻게 생겨먹은 메서드인겨…”라고 중얼거리게 된다.

보통 jd-gui 같은 디컴파일러를 쓴다. 다만 jd-gui 는 이클립스와 연동되지 않아 상당히 불편하다. 이클립스와 jd-gui, 이렇게 윈도우 2개를 동시에 켜고 번갈아 봐야하니까.

그런데 이클립스 자체에서 열 수 있는 방법이 있다. 기본 JDK 내의 Class 파일, 인터넷에서 다운받은 jar 내의 Class 파일 등을 이클립스 상에서 바로 바로 열어볼 수 있다.

(본 설명은 Eclipse Java EE IDE for Web Developers. Kepler Service Release 2 버전 기준입니다.)

1. 이클립스를 켠다.

2. 상단 메뉴의 Help – Eclipse Marketplace … 를 클릭한다.

3. Find (검색창) 란에 jadclipse 를 입력하여 검색한다.

4. Eclipse Class Decompiler 2.9.0 이 보일 것이다.

5. Intall 버튼을 누른다.

다음(Next), 다음, 다음… 그냥 쭉 다음을 눌러주는 다음 신공을 펼치면 알아서 설치되고 이클립스가 재기동된다.

이제 Class 파일을 열면 잘 열릴 것이다. 컨트롤+클릭 도 가능하다. 우왕 굳..

[JAVA] splitMulti 메서드

[JAVA] splitMulti 메서드

새로 만든 유용한 메서드. Split 과 기본적으로 같지만 딜리미터를 여러 개 사용 가능하다. 다른 점이라면 스트링 배열이 아니라 스트링 어레이리스트를 리턴해준다는 것 정도. 아래와 같이 쓰면 된다.

ex) ArrayList<String> inputList = StringUtil.splitMulti(inputText, “\r\n”, “\r”, “\n”, “;”);

———————————————————————-

/**
     * n개의 딜리미터로 split 처리
     *
     * @param fullStr
     * @param delimeters
     * @return
     */
    public static ArrayList<String> splitMulti(String fullStr, String… delimeters) {

        ArrayList<String> resList = new ArrayList<String>();

        if (fullStr == null || fullStr.length() == 0) {
            return null;
        }

        if (delimeters == null) {
            System.out.println(“splitMulti : delimeters are null”);
            return null;
        }

        int deliCount = delimeters.length;
        if (deliCount < 1) {
            System.out.println(“splitMulti : delimeters’ count is 0”);
            return null;
        }

        StringBuffer contentStack = new StringBuffer();

        int fullLen = fullStr.length();
        String oneDeli = “”;

        boolean isDeli = false;

        for (int i = 0; i < fullLen; i++) {
            isDeli = false;

            for (int k = 0; k < deliCount; k++) {
                oneDeli = delimeters[k];
                if (oneDeli == null || oneDeli.length() == 0) {
                    continue;
                }

                if (i + oneDeli.length() > fullLen) {
                    continue;
                }

                if (fullStr.substring(i, i + oneDeli.length()).equals(oneDeli)) {
                    resList.add(contentStack.toString());
                    contentStack.delete(0, contentStack.length());

                    // oneDeli 로 자른다.
                    isDeli = true;
                    break;
                }
            }

            if (!isDeli) {
                contentStack.append(fullStr.substring(i, i + 1));
            }
        }

        if (contentStack.length() > 0) {
            resList.add(contentStack.toString());
        }

        return resList;
    }

cos.jar

cos.jar

cos-26Dec2008.zip 파일 첨부하였습니다. 원래는 http://servlets.com/cos/ 에서 다운로드할 수 있습니다.

자바 유니코드 변환(encode, decode)

자바 유니코드 변환(encode, decode)

2016-11-14

인터넷에 돌아다니는 소스를 다소 수정하여 만들었음. by bb_

public static void main(String[] args) { 

    try {
        System.out.println(encode(“동해물과 백두산이 마르고 닳도록,”));
        System.out.println(decode(“\ub3d9\ud574\ubb3c\uacfc \ubc31\ub450\uc0b0\uc774 \ub9c8\ub974\uace0 \ub2f3\ub3c4\ub85d\u002c”));
        System.out.println(decode(encode(“동해물과 백두산이 마르고 닳도록,”)));
   
    }catch (Exception e) {
        e.printStackTrace();
    }
}

public static String decode(String unicodeStr) throws Exception {

    StringBuffer str = new StringBuffer();
    int i = -1;

    char ch = 0;
    String decodeStr = “”;   

    int nextBegin = -1;
  
        while ((i = unicodeStr.indexOf(“\\u“)) > -1) {
   
            if (i + 6 > unicodeStr.length()) {
                // 유니코드 값이 길이가 4자리가 안된다면 변환 무시
                decodeStr = “\\u” + unicodeStr.substring(i + 2);
                nextBegin = unicodeStr.length();
       

            } else {
                try {

                    ch = (char)Integer.parseInt(unicodeStr.substring(i + 2, i + 6), 16);
                    decodeStr = String.valueOf(ch);
                    nextBegin = i + 6;
     
                } catch (NumberFormatException e) {
                    // 유니코드 값이 16진수 포맷이 아니라면 변환 무시
                    decodeStr = “\\u” + unicodeStr.substring(i + 2, i + 6);
                    nextBegin = i + 6;
                }
            }
        str.append(unicodeStr.substring(0, i));
        str.append(decodeStr);
        unicodeStr = unicodeStr.substring(nextBegin);
    }
    str.append(unicodeStr);

    return str.toString();

}

public static String encode(String orgStr) throws Exception {

    StringBuffer str = new StringBuffer();
    int len = orgStr.length();

    for (int i = 0; i < len; i++) {

        if (((int)orgStr.charAt(i) == 32)) {
            str.append(” “);
            continue;
        }

        str.append(“\\u“);
        String hexCode = Integer.toHexString((int)orgStr.charAt(i));
        int space = 4 – hexCode.length();
        for(int k=0; k<space; k++) {
            str.append(“0”);
        }
        str.append(hexCode);
    }

    return str.toString();
} 

유니코드 한자 정규식 (한자 포함되어 있는지 확인)

유니코드 한자 정규식 (한자 포함되어 있는지 확인)

String target = “한자 포함되어 있는 문장 上海 “;
   
String regEx = “.*[\u2e80-\u2eff\u31c0-\u31ef\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fbf\uf900-\ufaff].*”;

if (target.matches(regEx)) {
    System.out.println(“일치”);
} else {
    System.out.println(“불일치”);
}

(참고 1) 유니코드 범위

http://blog.naver.com/bb_/220861227839

2E80 2EFF CJK Radicals Supplement 한중일 부수 보충
31C0 31EF CJK Strokes 한중일 한자 획
3200 32FF Enclosed CJK Letters and Months 한중일 괄호 문자
3400 4DBF CJK Unified Ideographs Extension A 한중일 통합 한자 확장-A
4E00 9FBF CJK Unified Ideographs 한중일 통합 한자
F900 FAFF CJK Compatibility Ideographs 한중일 호환용 한자

(참고 2)

// 원래는 [\u20000-\u2a6df\u2f800-\u2fa1f] 까지 포함되어 있었는데

// 역슬래시u + 5자리 유니코드는 일반적이지도 않고, (보통 역슬래시u + 4자리)

// 숫자랑 일반 알파벳이 섞여있어서, 5자리 유니코드는 뺐음.

20021 : !
20022 : “
20023 : #
20024 : $
20025 : %
20026 : &
20027 : ‘
20028 : (
20029 : )
20030 : 0
20031 : 1
20032 : 2
20033 : 3
20034 : 4
20035 : 5
20036 : 6
20037 : 7
20038 : 8
20039 : 9
20040 : @
20041 : A
20042 : B
20043 : C
20044 : D
20045 : E
20046 : F
20047 : G
20048 : H
20049 : I
20050 : P
20051 : Q
20052 : R
20053 : S
20054 : T
20055 : U
20056 : V
20057 : W
20058 : X
20059 : Y
20060 : `
20061 : a
20062 : b
20063 : c
20064 : d
20065 : e
20066 : f
20067 : g
20068 : h
20069 : i
20070 : p
20071 : q
20072 : r
20073 : s
20074 : t
20075 : u
20076 : v
20077 : w
20078 : x
20079 : y

유니코드 범위

유니코드 범위

 

처음 

영어 한국어
0000 007F Controls and Basic Latin 제어 문자와 라틴 기본
0080 00FF Controls and Latin-1 Supplement 제어 문자와 라틴 보충
0100 017F Latin Extended-A 라틴 확장-A
0180 024F Latin Extended-B 라틴 확장-B
0250 02AF IPA Extensions 국제 음성 기호 확장
02B0 02FF Spacing Modifier Letters 조정 문자
0300 036F Combining Diacritical Marks 조합 분음 기호(악센트)
0370 03FF Greek and Coptic 그리스어와 콥트어
0400 04FF Cyrillic 키릴 자모
0500 052F Cyrillic Supplementary 키릴 자모 보충
0530 058F Armenian 아르메니아어
0590 05FF Hebrew 히브리어
0600 06FF Arabic 아랍어
0700 074F Syriac 시리아어
0750 077F Arabic Supplement 아랍어 보충
0780 07BF Thaana 타아나어
07C0 07FF N’Ko 은코
0900 097F Devanagari 데바나가리어
0980 09FF Bengali 벵골어
0A00 0A7F Gurmukhi 굴묵키어
0A80 0AFF Gujarati 구자라트어
0B00 0B7F Oriya 오리야어
0B80 0BFF Tamil 타밀어
0C00 0C7F Telugu 텔루구어
0C80 0CFF Kannada 칸나다어
0D00 0D7F Malayalam 말라얄람어
0D80 0DFF Sinhala 신할라어
0E00 0E7F Thai 타이어
0E80 0EFF Lao 라오어
0F00 0FFF Tibetan 티베트어
1000 109F Myanmar 미얀마어
10A0 10FF Georgian 그루지야어
1100 11FF Hangul Jamo 한글 자모
1200 137F Ethiopic 에티오피아어
1380 139F Ethiopic Supplement 에티오피아어 보충
13A0 13FF Cherokee 체로키어
1400 167F Unified Canadian Aboriginal Syllabics 통합 캐나다 원주민 소리 마디
1680 169F Ogham 오검 문자
16A0 16FF Runic 룬 문자
1700 171F Tagalog 타갈로그어
1720 173F Hanunoo 하누누어
1740 175F Buhid 부히드어
1760 177F Tagbanwa 타그반와어
1780 17FF Khmer 크메르어(캄보디아어)
1800 18AF Mongolian 몽골어
1900 194F Limbu 림부
1950 197F Tai Le 타이 레 문자
1980 19DF New Tai Lue 새 타이 루에
19E0 19FF Khmer Symbols 크메르 기호
1A00 1A1F Buginese 부기 문자
1B00 1B7F Balinese 발리 문자
1D00 1D7F Phonetic Extensions 음성 부호 확장
1D80 1DBF Phonetic Extensions Supplement 음성 부호 확장 보충
1DC0 1DFF Combining Diacritical Marks Supplement 조합 분음 부호(악센트) 보충
1E00 1EFF Latin Extended Additional 라틴어 추가 확장
1F00 1FFF Greek Extended 그리스어 확장
2000 206F General Punctuation 일반 구두점
2070 209F Superscripts and Subscripts 위 첨자와 아래 첨자
20A0 20CF Currency Symbols 화폐 기호
20D0 20FF Combining Diacritical Marks for Symbols 조합 분음 부호(기호)
2100 214F Letterlike Symbols 글자를 변형한 기호
2150 218F Number Forms 여러 가지 수
2190 21FF Arrows 화살표
2200 22FF Mathematical Operators 수학 연산자
2300 23FF Miscellaneous Technical 여러 가지 기술 기호
2400 243F Control Pictures 제어 문자 기호
2440 245F Optical Character Recognition 문자 인식(OCR) 기호
2460 24FF Enclosed Alphanumerics 괄호 문자
2500 257F Box Drawing 상자 그리기 기호
2580 259F Block Elements 네모 기호
25A0 25FF Geometric Shapes 도형 기호
2600 26FF Miscellaneous Symbols 여러 가지 기호
2700 27BF Dingbats 딩뱃 기호
27C0 27EF Miscellaneous Mathematical Symbols-A 여러 가지 수학 기호-A
27F0 27FF Supplemental Arrows-A 화살표 보충-A
2800 28FF Braille Patterns 점자
2900 297F Supplemental Arrows-B 화살표 보충-B
2980 29FF Miscellaneous Mathematical Symbols-B 여러 가지 수학 기호-B
2A00 2AFF Supplemental Mathematical Operators 수학 연산자 보충
2B00 2BFF Miscellaneous Symbols and Arrows 여러 가지 기호와 화살표
2C00 2C5F Glagolitic 글라골리틱 문자
2C60 2C7F Latin Extended-C 라틴 확장-C
2C80 2CFF Coptic 콥트어
2D00 2D2F Georgian Supplement 그루지야어 보충
2D30 2D7F Tifinagh 티피나그
2D80 2DDF Ethiopic Extended 에티오피아어 보충
2E00 2E7F Supplemental Punctuation 구두점 보충
2E80 2EFF CJK Radicals Supplement 한중일 부수 보충
2F00 2FDF KangXi Radicals 강희자전 부수
2FF0 2FFF Ideographic Description characters 한자 생김꼴 지시 부호
3000 303F CJK Symbols and Punctuation 한중일 기호 및 구두점
3040 309F Hiragana 히라가나
30A0 30FF Katakana 가타카나
3100 312F Bopomofo 주음 부호
3130 318F Hangul Compatibility Jamo 호환용 한글 자모
3190 319F Kanbun 훈독 순서 지시 부호
31A0 31BF Bopomofo Extended 주음 부호 확장
31C0 31EF CJK Strokes 한중일 한자 획
31F0 31FF Katakana Phonetic Extensions 가타카나 음성 확장
3200 32FF Enclosed CJK Letters and Months 한중일 괄호 문자
3300 33FF CJK Compatibility 한중일 호환용
3400 4DBF CJK Unified Ideographs Extension A 한중일 통합 한자 확장-A
4DC0 4DFF Yijing Hexagram Symbols 역경 6줄 기호
4E00 9FBF CJK Unified Ideographs 한중일 통합 한자
A000 A48F Yi Syllables 이(Yi) 소리 마디
A490 A4CF Yi Radicals 이(Yi) 부수
A700 A71F Modifier Tone Letters 어조 조정 문자
A720 A7FF Latin Extended-D 라틴 확장-D
A800 A82F Syloti Nagri 실헤티 나가리
A840 A87F Phags-Pa 파스파 문자
AC00 D7AF Hangul Syllables 한글 소리 마디
D800 DBFF High Surrogate Area 상위 대체 영역
DC00 DFFF Low Surrogate Area 하위 대체 영역
E000 F8FF Private Use Area 사용자 영역
F900 FAFF CJK Compatibility Ideographs 한중일 호환용 한자
FB00 FB4F Alphabetic Presentation Forms 영문 표현꼴
FB50 FDFF Arabic Presentation Forms-A 아랍어 표현꼴-A
FE00 FE0F Variation Selectors 모양 구별 문자
FE10 FE1F Vertical Forms 세로쓰기 모양
FE20 FE2F Combining Half Marks 조합용 반쪽 기호
FE30 FE4F CJK Compatibility Forms 한중일 호환용 꼴
FE50 FE6F Small Form Variants 작은꼴 변형
FE70 FEFF Arabic Presentation Forms-B 아랍어 표현꼴-B
FF00 FFEF Halfwidth and Fullwidth Forms 전각/반각 모양
FFF0 FFFF Specials 특수 제어 문자
10000 1007F Linear B Syllabary 선상 B 음절 문자
10080 100FF Linear B Ideograms 선상 B 상형 문자
10100 1013F Aegean Numbers 에게(Aegean) 숫자
10140 1018F Ancient Greek Numbers 옛 그리스 숫자
10300 1032F Old Italic 옛 이탈리아 문자
10330 1034F Gothic 옛 고딕체 알파벳
10380 1039F Ugaritic 우가리트 문자
103A0 103DF Old Persian 옛 페르시아 문자
10400 1044F Deseret 데저렛 문자
10450 1047F Shavian 샤우 문자
10480 104AF Osmanya 오스마니아 문자
10800 1083F Cypriot Syllabary 키프로스 음절 문자
10900 1091F Phoenician 페니키아 문자
10A00 10A5F Kharoshthi 카로슈티
12000 123FF Cuneiform 쐐기 문자
12400 1247F Cuneiform Numbers and Punctuation 쐐기 문자 숫자·문장 부호
1D000 1D0FF Byzantine Musical Symbols 비잔틴 시대의 악보용 기호
1D100 1D1FF Musical Symbols 악보용 기호
1D200 1D24F Ancient Greek Musical Notation 고대 그리스 시대의 악보용 기호
1D300 1D35F Tai Xuan Jing Symbols 태현경 기호
1D400 1D7FF Mathematical Alphanumeric Symbols 수학식에서 쓰이는 알파벳
20000 2A6DF CJK Unified Ideographs Extension B 한중일 통합 한자 확장-B
2F800 2FA1F CJK Compatibility Ideographs Supplement 한중일 호환용 한자 보충
E0000 E007F Tags 태그
E0100 E01EF Variation Selectors Supplement 모양 구별 문자 보충
F0000 FFFFF Supplementary Private Use Area-A 사용자 영역 보충-A
100000 10FFFF Supplementary Private Use Area-B 사용자 영역 보충-B

출처 : http://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%EB%B2%94%EC%9C%84_%EB%AA%A9%EB%A1%9D

출처 : http://duellist.tistory.com/118

JQuery html의 tagName 얻기

JQuery html의 tagName 얻기

제이쿼리 html 태그명 알아내는 법.

var targetTagName = $(“#certainId”).prop(“tagName”);

하면 된다.

예를 들어 <form id=”certainId”></form> 이면 “FORM”을 얻는다.

참고 :

var str = “FORM”;

str = str.toUpperCase(); //  str == “FORM” 가 된다.

str = str.toLowerCase(); //  str == “form” 가 된다.

jquery ajax 기초

jquery ajax 기초

function sendPost () {
    var url = “test.jsp”; 
    var params= ” a=111&b=222″;

    // 참고 : $( “form” ).serialize();
  
    $.ajax({
        type : “POST”, 
        url : url,
        data : params,     
        success : function(result) {

             alert(“결과 : ” + result);
        },  
        // beforeSend : showRequest, 
        error : function(e){ 
            alert(e.responseText); 
        } 
    });     
}

자바 정규식 기초

자바 정규식 기초

String regEx = “.*”

– 모든 문자

String regEx = “[0-9][0-9][0-9][0-9][0-9]”;

– 숫자 5자리

String regEx = “^[0-9].*[0-9]$”;

– 숫자로 시작해서 숫자로 끝남

String regEx = “\\d{3}”;

– 숫자 3자리

String regEx = “\\d{1,5}”;

– 숫자 1자리 이상 5자리 이하

실제로 쓰는 방법.

String target = “분석이 필요한 스트링”;

String regEx = “.*”; // 일 때,

if (target.maches(regEx)) {

    // 정규식 조건 충족

} else {

    // 정규식 조건 미충족

}

// 위와 같이 쓰면 됨.

svn compare시 한글 깨질 경우 utf-8 변환법

svn compare시 한글 깨질 경우 utf-8 변환법

window – preferences 에서

좌측 상단 텍스트 박스에 encoding 으로 검색한다.

좌측 메뉴의 General  – Workspace 를 클릭하여

Text file encoding 을 UTF-8로 설정해준다.

document.oncontextmenu 와 마우스 우클릭

document.oncontextmenu 와 마우스 우클릭

1. 마우스 우클릭 시 펑션 실행 

자바스크립트에서 document.oncontextmenu 가 기본값(null)이면 마우스 우클릭 가능.

= function(){} 으로 펑션 대입하면 마우스 우클릭시 펑션 실행.

2. 마우스 우클릭 막기

마우스 우클릭 막으려면 함수를 대입하되 내용을 비워두면 됨.

혹은

function document.oncontextmenu() {
    return false;
}

식으로 쓴다.

혹은

document.onselectstart = new function() {

    return false;
}

식으로 쓴다.

3. 참고

function document.onselectstart() {
    return false;
}
function document.ondragstart() {
    return false;
}

톰캣 8.0 초기세팅 (Tomcat 8.0)

톰캣 8.0 초기세팅 (Tomcat 8.0)

1. server.xml 에서 포트 변경.

<Connector connectionTimeout=”20000″ port=”8080″ protocol=”HTTP/1.1″ redirectPort=”8443″/>

포트를 8080 에서 80 으로 변경

localhost:8080 으로 접속해야 하는 것을 localhost 로 바로 접속할 수 있게 해준다.

2. server.xml 에서 Context 변경.

<Context docBase=”프로젝트명” path=”/프로젝트명” reloadable=”true” source=”org.eclipse.jst.jee.server:프로젝트명”/></Host>

위와 같이 쓰면 “localhost:포트번호/프로젝트명”이라고 주소 입력하였을 때 서블릿으로 연결된다.

<Context docBase=”프로젝트명” path=”/” reloadable=”true” source=”org.eclipse.jst.jee.server:프로젝트명”/></Host>

위와 같이 수정하면 “localhost:포트번호/”이라고 주소 입력하였을 때 서블릿으로 연결된다.

윈도우 정품인증 상태 확인 명령어

윈도우 정품인증 상태 확인 명령어

1. 시작 – 실행 – cmd

2. slmgr /dlv 입력 후 엔터 

jsp 파일 업로드 참고 : request.getInputStream

jsp 파일 업로드 참고 : request.getInputStream

 

public void doPost( HttpServletRequest req, HttpServletResponse resp ) throws Exception {
  
  String reqContentType = req.getContentType();
  System.out.println( “reqContentType : ” + reqContentType );
  
  InputStream input = req.getInputStream();
  ByteArrayOutputStream result = null;
  PrintWriter writer = null;
  
  try{
   
   input = req.getInputStream();
   result = new ByteArrayOutputStream();
   
   byte[] buffer = new byte[1024]; // 한 번 읽을때마다 1024씩
   int size=0;
        
   while((size=input.read(buffer, 0, 1024))!=-1){
    //-1 이 EOF

    System.out.println(“size : ” + size);
    result.write( buffer, 0, size );
   }
   
   // System.out.println( b.toString(“UTF-8”) );
   
   // 폴더 만든다
   File dir = new File( “c:/result/” );
   if ( !dir.exists() ) {
    dir.mkdir();
   }
   
   // 파일 만든다
   File file = new File( “c:/result/aa.txt” );
   
   if ( !file.exists() ) {
    file.createNewFile();
   }

   // 내용 쓴다
   writer = new PrintWriter( file );
   writer.println( result.toString(“UTF-8”) );
   writer.close();

  } catch ( Exception e ) {
   e.printStackTrace();
   
  } finally {
   
   try {
    if ( input != null ){
     input.close();
    }
   } catch ( Exception e ) {
    input = null;
   }
   
   try {
    if ( result != null ) {
     result.close();
    }
   } catch ( Exception e ) {
    result = null;
   }
   
   try {
    if ( writer != null ) {
     writer.close();
    }
   } catch ( Exception e ) {
    writer = null;
   }
   
  }

}

자바 파일쓰기(Printwriter) (2016/09/08 보완)

자바 파일쓰기(Printwriter)

 

자바에서 Printwriter 객체를 이용하여 간단하게 파일을 쓸 수 있다.

 

File file = new File( “c:/aa.txt” );

Printwriter w = new PrintWriter( file );

w.println( “111” );

w.print( “222” );

w.close();

 

——————–

 

오전 1:25 2016-09-08

자바 파일쓰기(Printwriter) (2016/09/08 보완)

 

try {

   // 폴더 만든다
   File dir = new File( “c:/result/” );
   if ( !dir.exists() ) {
    dir.mkdir();
   }
   
   // 파일 만든다
   File file = new File( “c:/result/aa.txt” );
   
   if ( !file.exists() ) {
    file.createNewFile();
   }

 

   // 내용 쓴다
   writer = new PrintWriter( file );
   writer.println(  );
   writer.close();

 

} catch ( Exception e ) {

   e.printStackTrace();

 

} finally {

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

}

텍스트 파일에 담긴 SQL문 통째로 실행하는 법

텍스트 파일에 담긴 SQL문 통째로 실행하는 법

1. 적당한 위치 (씨 드라이브의 foo 폴더라 해보자)에 폴더를 만든다.

2. 그 폴더 안에 텍스트 파일을 넣는다. 텍스트 파일 안에는 SQL문장만 잔뜩 써놓는다. 이 때 확장자는 sql로 한다. 예를 들면 파일명이 boo.sql 이라고 하자. SQL문 외에는 앞에 하이픈 두 개 (–)를 붙여 주석처리하자.

3. 시작 – 실행 – cmd 로 도스창을 켜고, cd 명령어를 이용해 만들어 놓은 foo 폴더로 이동하자.

4. sqlplus 아이디/비번@디비스키마이름

5. set heading off

헤더 필요 없다.

6. set pagesize 0

페이지 나누기 따위 없다.

7. set linesize 2000

가로 길이를 무지하게 넓게 잡아서 SQL결과가 엔터로 나뉘지 않도록 함

8. spool newfilename

9. @boo

그러니까, 골뱅이 뒤에 실행시킬 sql파일 이름을 쓴다.

10. spool off

하면 해당 폴더에 newfilename 이라는 이름으로 파일 써짐.

끝.

VBA/VB6 엔터를 구분자로 스트링 나누기 하기(Split), 배열의 크기(UBound, LBound) 얻기

VBA/VB6 엔터를 구분자로 스트링 나누기 하기(Split), 배열의 크기(UBound, LBound)

 

엔터를 구분자로 Split 하기

    Dim tArray

    tArray = Split(str, vbCrLf, , vbTextCompare)

 

    ※ vbCrLf 은 엔터를 뜻한다. 캐리지 리턴, 라인 피드. 각각 나눠서 vbCr, vbLf 로도 각각 쓸 수 있다.

    – 엑셀의 각 셀을 대상으로 vba 코딩을 하고 있다면, 엑셀은 vbCrLf 가 아니라 vbLf 를 인자값으로 넣어야 문자를 인식한다. 또한 vbTextCompare 옵션을 꼭 넣어줘야 인식한다.

    – vbTextCompare 옵션은 대소문자를 구별하지 않겠다는 의미이다.

 

Split( 스트링, 바꿀 문자, 바꿀 갯수(미입력시 무제한을 나타내는 -1), 옵션 )

 

배열의 크기 얻기

    Dim tArraySize
    tArraySize = UBound(tArray) – LBound(tArray) + 1

 

예제

    ‘엔터가 포함된 스트링
    Dim str
    str = “내용1” + vbCrLf
    str = str + “내용2” + vbCrLf
    str = str + “내용3” + vbCrLf
    str = str + “내용4”
   
    ‘배열
    Dim tArray
   
    ‘스트링을 엔터를 기준으로 잘라서 배열화
    tArray = Split(str, vbCrLf, , vbTextCompare)
   
    ‘배열 사이즈 구하기
    Dim tArraySize
    tArraySize = UBound(tArray) – LBound(tArray) + 1
   
    ‘배열 내용 출력
    For i = 0 To tArraySize – 1
        MsgBox (tArray(i))
    Next i

java.lang.IllegalStateException: Cannot forward after response has been committed

java.lang.IllegalStateException: Cannot forward after response has been committed

 

위와 같은 에러 메시지를 봤을 때, 결론부터 말하면, 인크루드를 사용하자.

 

개인적으로 간단한 경량 웹 프레임워크를 만들고 있는데, 서블릿 단에서 위와 같은 에러가 발생했다. forward 하기 이전에 response의 Writer를 얻어 내용을 썼기 때문이다.

 

처음부터 하나씩 설명하면, 먼저 자바에서 HttpServlet을 상속한 어떤 서블릿이 doPost, doGet 메소드를 오버라이드한 상태라고 해보자. 이 때 보통은 doPost, doGet 내부에서 forward로 원하는 경로의 jsp로 이동시킨다.

예를 들면 아래와 같은 식이다.

 

RequestDispatcher dispatcher = req.getRequestDispatcher( “원하는/경로의/파일.jsp” );
dispatcher.forward( req, res );

 

그런데 이 jsp에, 내가 원하는 코드를 동적으로 합쳐서 jsp를 만들어보내고 싶다고 해보자. 나의 경우엔 에러메시지를 담아 보내거나, js변수들을 서버 단에서 만들어 보낼 작정이었다.

 

그렇다면 response에서 getWriter를 사용하여 Writer 객체를 얻고, write 함수로 내용을 넣으면 된다. 이것이 스프링에서의 @ResponseBody기능이다.

 

그런데 forward 전에, 아래와 같이 response에 무언가를 쓰는 행위를 했다고 하면 에러가 난다.

 

res.setCharacterEncoding(“UTF-8”);
res.getWriter().write(“<script> alert(‘Hello World’); </script>”);
res.getWriter().flush();

 

기본적으로 res에 write를 하고 flush를 하면 그것으로 끝난거지(그것이 페이지의 전부이다!), 이후에 forward를 쓸 수 없다. 그랬다간 java.lang.IllegalStateException: Cannot forward after response has been committed 에러가 난다.

 

스프링에서도 위와 같은 기능(기존 jsp에 원하는 코드를 동적으로 합쳐 내보내는 기능)은 지원하지 않기 때문에, 현재로서는 특정 컨트롤러 메소드에 @ResponseBody 어노테이션을 붙여놓고, ajax로 해당 부분을 불러오는 방법을 쓴다. 다시 말해서 jsp단 ajax 코드가  필수적이다.

 

나는 jsp에 일일히 코드가 들어가길 원하지 않았다. 그저 기존에 존재하는 jsp에, 원하는 에러메시지 스크립트를 합쳐서 보내고 싶었다. 안타깝게도 redirect를 써도 소용이 없다.

 

res.sendRedirect( “원하는/경로의/파일.jsp” );

 

라고 보내면 java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed 에러가 뜬다. 마찬가지로 내용을 쓰고 나서 redirect를 해선 안된다. 더구나 sendRedirect는 forward와 달리 Attribute가 전달되지 않는다. 스프링으로 치면 모델 단에서 작업한 내용이 유실되는 셈이다. (그래서 스프링은 jsp 단에서 ajax로 한 번 더 부르는 방식을 사용한다.)

 

방법은 있다. include를 쓰는 것이다.

 

jsp 단에서 include를 부르느니 ajax와 차이가 없기 때문에, 서버 단에서 부른다. 아래와 같이 코딩하면 된다.

 

req.setAttribute(“myName”, “흑곰”); //테스트용 코드

 

res.setCharacterEncoding(“UTF-8”);   
RequestDispatcher dispatcher = req.getRequestDispatcher( “원하는/파일의/경로.jsp” );
dispatcher.include( req, res );

res.getWriter().write(“<script> alert(‘Hello World’); </script>”);
res.getWriter().flush();

 

이렇게 include를 사용하면 된다. 이제 jsp에 동적으로 원하는 코드가 삽입된다. 해당 jsp에 ${myName}이라고 써넣고 어트리뷰트도 잘 넘어오는지 확인하자.

여기서 포인트는, Writer의 write와 flush를 뒤에 써준다는 것이다. 스스로 알아냄.

Failed to load the JNI shared library “jvm.dll”.

Failed to load the JNI shared library “jvm.dll”.

 

 

위와 같은 alert이 뜨면서 이클립스가 실행되지 않는 경우가 있다. 보통 내컴퓨터 우클릭 – 속성 – 설정변경 – 환경변수에서 시스템변수 JAVA_HOME과 시스템 변수 PATH를 다시 잡아주면 해결된다.

 

그러나 아무리 JAVA_HOME과 PATH를 다시 잡아도 이클립스가 해당 경로를 인식하지 못하는 경우가 있는데, 이 경우 아래와 같이 eclipse.ini 파일을 수정하면 된다.

 

주로 bit차이 때문에 일어나는 문제이다. 컴퓨터 내에 32비트와 64비트를 각각 깔아두고, 32비트 폴더 내의 jvm.dll이 존재하는 경로를 설정하여 해보고, 안되면 64비트 폴더 내의 jvm.dll이 존재하는 경로를 설정해서 시도해보자.


스프링에서 하둡 연동

스프링에서 하둡 연동

현재 hadoop은 버전 2.7까지 나와있지만, 스프링에서는 높은 버전을 쓸 수 없다. 현재 hadoop-core 라이브러리(스프링에서 하둡을 바로 붙을 수 있도록 지원)가 1.2.1 까지 밖에 지원이 안된다. 하둡을 1.2.1로 깔고 그것에 나머지 하둡 에코시스템을 맞춰야하는 한계점이 있다.

1. hadoop-core 

<!– http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-core –>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-core</artifactId>
    <version>1.2.1</version>
</dependency>
 


2. app.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans
    xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
    xmlns:aop=”http://www.springframework.org/schema/aop
    xmlns:context=”http://www.springframework.org/schema/context
    xmlns:hadoop=”http://www.springframework.org/schema/hadoop
    xmlns:p=”http://www.springframework.org/schema/p
    xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/hadoop http://www.springframework.org/schema/hadoop/spring-hadoop.xsd“>

    <!– 메모리 할당 –>
    <context:annotation-config/>
    <context:component-scan base-package=”com.com.*”></context:component-scan>
   
    <!– 하둡 설정 –>
    <!– private Configuration conf; –>
    <hadoop:configuration id=”hadoopConf”>
        fs.default.name=hdfs://localhost:9000
    </hadoop:configuration>

   
</beans>

3. FileSystemMain.java

package com.sist.movie;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component(“fsm”)
public class FileSystemMain {
   
    @Autowired
    private Configuration conf;
   
    public static void main(String[] args) {
        //Component: 자동메모리 할당
        //Autowired : 주소값 설정
       
        try{
           
            ApplicationContext app = new ClassPathXmlApplicationContext(“app.xml”);
           
            FileSystemMain fm = (FileSystemMain) app.getBean(“fsm”);
           
            FileSystem fs = FileSystem.get(fm.conf);
           
            1) 로컬에서 하둡으로 파일 보내기
            fs.copyFromLocalFile(new Path(“/home/sist/emp.csv”),
                                    new Path(“/input/emp.csv”) );
           
            //(2) 하둡에서 로컬로 파일 보내기
//            fs.copyToLocalFile(new Path(“/input/emp.csv”),
//                                    new Path(“./”) );
           
            //(3) 하둡 내의 파일 삭제하기
            //if( fs.exists(new Path(“/input/emp.csv”))){ //존재하면
            //    fs.delete(new Path(“/input/emp.csv”), true); //삭제

                // 두번째 매개변수에 true를 주면 안쪽 파일까지 삭제되는 것
                // ( 리눅스의 rm -rf와 같음. 하둡에서는 -rmr )
            //}
           
            fs.close();
           
            System.out.println(“파일전송완료”);
        }catch(Exception e){
            System.out.println(“main error :”);
            e.printStackTrace();
        }
    }
}

자바에서 하이브 사용하기

자바에서 하이브 사용하기

1. 하이브 스타트

설치된 하이브를 스타트 시킨다. 터미널에서 hive –service hiveserver 명령어를 치면 자바에서 접근할 수 있게 하이브를 기동시킨다.

참고)

(1) 하이브 설치 : http://blog.naver.com/bb_/220739646411

(2) 하이브 실행 : http://blog.naver.com/bb_/220739653295

2. 라이브러리 가져오기

maven 기준으로 가져와야 하는 라이브러리를 나열하겠다.

(1) Hive Query Language 0.9.0

<!– http://mvnrepository.com/artifact/org.apache.hive/hive-exec –>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>0.9.0</version>
</dependency>
 

(2) Hive Metastore 0.9.0 

<!– http://mvnrepository.com/artifact/org.apache.hive/hive-metastore –>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-metastore</artifactId>
    <version>0.9.0</version>
</dependency>

(3) Hive Service 0.9.0  

<!– http://mvnrepository.com/artifact/org.apache.hive/hive-service –>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-service</artifactId>
    <version>0.9.0</version>
</dependency>

(4) Hive Common 0.9.0  

<!– http://mvnrepository.com/artifact/org.apache.hive/hive-common –>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-common</artifactId>
    <version>0.9.0</version>
</dependency>

(5) Hive JDBC 0.9.0  

<!– http://mvnrepository.com/artifact/org.apache.hive/hive-jdbc –>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>
    <version>0.9.0</version>
</dependency>
 

(6) JDO2 API 2.0  

<!– http://mvnrepository.com/artifact/javax.jdo/jdo2-api –>
<dependency>
    <groupId>javax.jdo</groupId>
    <artifactId>jdo2-api</artifactId>
    <version>2.0</version>
</dependency>

3. 테이블을 select해서 읽는 자바 소스

package com.com.hive;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class HiveMain {

    public static void main(String[] args) {
        Connection conn = null;
        ResultSet rs = null;
       
        try{
           
            String driver = “org.apache.hadoop.hive.jdbc.HiveDriver”;
            Class.forName(driver);
           
            String url = “jdbc:hive://localhost:10000/default”;
            //기본 포트가 10000 번이고, 기본데이터베이스 이름이 defualt 임.
            String id = “hive”;
            String pw = “hive”;
           
            conn = DriverManager.getConnection(url, id, pw);
           
            String sql = “SELECT * FROM dept”;
            Statement stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
           
            while(rs.next()){
                String col1 = rs.getString(1);
                String col2 = rs.getString(2);
                String col3 = rs.getString(3);
                       
                System.out.println( col1 + “/” + col2 + “/” + col3 );
            }
           
            rs.close();
            conn.close();
           
        }catch(Exception ex){
            System.err.println(“main error :”);
            ex.printStackTrace();
        }finally {
            try{
                if( rs != null ){
                    rs.close();               
                }
            }catch(Exception ex){
                rs = null;
            }
           
            try{
                if( conn != null ){
                    conn.close();               
                }
            }catch(Exception ex){
                conn = null;
            }
        }
    }

}
 

하이브(hive) 테이블 만들기

하이브(hive) 테이블 만들기

1, 하이브 설치

http://blog.naver.com/bb_/220739646411

2. 하이브 실행

터미널을 켜서 hive 라고 친다.

3. 하이브로 들어왔으면 show tables; 이라고 쳐서 OK 값이 나와야 정상.

에러가 떨어지면 읽어보고 설정파일을 수정한다. 패스워드와 아이디가 맞는지 확인해본다.

4. 테이블 만들기

create table dept(dname string,loc string,deptno int)  엔터
row format delimited fields terminated by ‘,’;   엔터

load data local inpath ‘/home/sist/dept.csv’ overwrite into table dept; 엔터

하면 dept.csv파일(쉼표를 구분자로 한 파일) 을 읽어서 테이블로 만든다.

5. 테이블 조회

select * from dept;

6. 하이브 종료

exit; 로 종료한다.

7. 참고) 하이브 스타팅

자바에서 접근할 수 있게 기동시킬 수 있다.

hive –service hiveserver

하이브 설치 기초(hive-0.9.0)

하이브 설치 기초(hive-0.9.0)

1. mysql 설치 

(1) mysql 설치 : sudo apt-get install mysql-server

(2) sql 접속 : mysql -u root -p

(3) 권한주기 : grant all privileges on *.* to ‘hive’@localhost identified by ‘hive’;

(4) 빠져나와서 하이브 유저로 sql 접속 : mysql -u hive -p

hive> 로 접속되면 됨.

2. 구글에서 hive-0.9.0.tar.gz 검색해서 다운로드

3. 해당 파일 압축 풀고 로컬 폴더로 이동시키기

/usr/local/hive-0.9.0

4. 환경설정 파일 수정

sudo nano /etc/environment

PATH 뒤쪽에 내용추가. (따옴표 안쪽 부분에 콜론을 붙이고 이어 쓰면 됨)

PATH = “……..:/usr/local/hive-0.9.0/bin”

HIVE_HOME=”/usr/local/hive-0.9.0″

5. Hive설정 파일 수정 

폴더 경로 /usr/local/hive-0.9.0/conf 로 간다.

(1) hive-env.sh.template 을 복사 떠서 hive-env.sh 라는 이름으로 만든다.

(2) hive-default.xml.template 를 복사 떠서 hive-site.sh 라는 이름으로 만든다.

6. hive-env.sh 파일 수정하기 

(1) #export HADOOP_HEAPSIZE=1024 를 찾아서

앞의 샵 떼고 export HADOOP_HEAPSIZE=4096 로 변경

(2) # HADOOP_HOME=${bin}/../../hadoop 을 찾아서

앞의 샵 떼고 HADOOP_HOME=/usr/local/hadoop-1.2.1 로 변경 (실제 하둡 경로를 지정)

(3) # export HIVE_CONF_DIR= 을 찾아서

앞의 샵 떼고 export HIVE_CONF_DIR=/usr/local/hive-0.9.0/conf 로 변경

6. hive-site.xml 수정하기

컨트롤 F키를 이용해서 특정 문구를 찾고 변경하는 작업을 한다.

(1) <property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:derby:;databaseName=metastore_db;create=true</value>
  <description>JDBC connect string for a JDBC metastore</description>
</property>

를 찾아서

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://localhost:3306/metastore_db?createDatabaseIfNotExist=true</value>
  <description>JDBC connect string for a JDBC metastore</description>
</property>

로 변경

(2) <property>
  <name>javax.jdo.option.ConnectionDriverName</name>
  <value>org.apache.derby.jdbc.EmbeddedDriver</value>
  <description>Driver class name for a JDBC metastore</description>
</property>

를 찾아서

<property>
  <name>hive.stats.jdbcdriver</name>
  <value>com.mysql.jdbc.Driver</value>
  <description>The JDBC driver for the database that stores temporary hive statistics.</description>
</property>

로 변경

(3) <property>
  <name>javax.jdo.option.ConnectionUserName</name>
  <value>hive</value> #이 부분에 아이디 넣기
  <description>username to use against metastore database</description>
</property>

<property>
  <name>javax.jdo.option.ConnectionPassword</name>
  <value>hive</value> #이 부분에 비밀번호 넣기
  <description>password to use against metastore database</description>
</property>

를 찾아서 아이디 밸류와 패스워드 밸류를 변경

(4) <property>
  <name>hive.metastore.warehouse.dir</name>
  <value>/user/hive/warehouse</value>
  <description>location of default database for the warehouse</description>
</property>

의 밸류값을 기억하기. 변경할건 없음.

7. 터미널 들어가서 세팅

hadoop dfs -mkdir /tmp
hadoop dfs -mkdir /user/hive/warehouse
hadoop dfs -chmod g+w /user/hive/warehouse
hadoop dfs -chmod g+w /tmp

8. mysql-connector-java-5.1.22.jar 을 받아서

/usr/local/hive-0.9.0/lib 안에 붙여넣기한다.

9. 하이브 실행 

터미널에  source /etc/environment 라고 친다.

터미널에서 hive라고 친다.

아래처럼 나오면 실행되는 것이다.

WARNING: org.apache.hadoop.metrics.jvm.EventCounter is deprecated. Please use org.apache.hadoop.log.metrics.EventCounter in all the log4j.properties files.
Logging initialized using configuration in jar:file:/usr/local/hive-0.9.0/lib/hive-common-0.9.0.jar!/hive-log4j.properties
Hive history file=/tmp/sist/hive_job_log_sist_201606181517_383526935.txt
hive>

 

주키퍼 설치 기초(zookeeper-3.3.6)

주키퍼 설치 기초(zookeeper-3.3.6)

1. 구글에서 zookeeper-3.3.6.tar.gz 검색해서 다운로드

2. 해당 파일 압축 풀고 로컬 폴더로 이동시키기

/usr/local/zookeepr-3.3.6

3. 환경설정 파일 수정

sudo nano /etc/environment

PATH 뒤쪽에 내용추가.

PATH = “……..:/usr/local/zookeeper-3.3.6/bin”

ZOOKEEPER_HOME=”/usr/local/zookeeper-3.3.6″

4. /home/hadoop/zk_data 폴더 생성

5. zk_data폴더 안에 myid 라는 파일 생성

vi myid 해서 안의 내용은 ‘1’ 딱 한 글자만 주고 저장(wq!)

6. conf파일 수정

/usr/local/zookeeper-3.3.6/conf 폴더 안의 zoo-sample.cfg파일 수정하기

(1) dataDir=/home/hadoop/zk_data 로 수정

(2)맨 아래 줄에 (clientPort=2181 아래줄) server.1=localhost:2888:3888 라고 입력 후 저장

(3) 파일명을 zoo-sample.cfg에서 zoo.cfg로 변경하기

7. 주키퍼 서버 실행

cd 해서 홈으로 온 다음

zkServer.sh start

8. 주키퍼 클라이언트 실행

zkCli.sh start

하둡 기동시 Namenode나 Datanode 올라오지 않을 때

하둡 기동시 Namenode나 Datanode 올라오지 않을 때

하둡 기동하다 보면 열 받는 때가 한 두번이 아니다. start-all.sh 명령어로 하둡을 처음 기동한 후 jps 라는 명령어를 치면 기본적으로 아래 6가지의 프로세스가 떠 있어야 한다.

TaskTracker, JobTracker, NameNode, DataNode, SecondaryNameNode, Jps

그런데 stop-all.sh 로 하둡을 껐다가 다음에 다시 start-all.sh 을 하면 5개만 올라오는 경우가 있다. 주로 Namenode가 없거나 Datanode가 없는 경우다. 단지재기동, 껐다 켰을 뿐인데 하둡이 깨져버리는(?) 현상이 잦다. 개인적으로 하둡을 사용할 때 가장 불만스러운 부분이다.

1. 작업 대상 폴더가 잘못된 경우 

우선 하둡 작업을 하는 대상 폴더들의 위치를 아래와 같이 가정한다.

/home/hadoop/hdfs/data – 데이터노드용 폴더. hdfs-site.xml 에서 설정.

/home/hadoop/hdfs/name – 네임노드용 폴더. hdfs-site.xml 에서 설정.

/home/hadoop/hdfs/mapred – 맵리듀스용 폴더. 분석 결과를 모아놓는다. mapred-site.xml 에서 설정.

/home/hadoop/hdfs/temp – 임시 폴더. 공통으로 사용한다. core-site.xml 에서 설정.

 

이 때 각 xml 에서 작업 폴더의 주소를 존재하지 않거나 잘못된 주소로 설정할 경우 에러가 난다.

2. jps를 쳤을 때 Namenode 올라오지 않을 경우 해결

대표적인으로 20ms 이내에 기동했던 하둡을 끄고 재기동하는 경우에 네임노드가 올라오지 않을 수 있다고 한다. 아니, 잘 꺼졌다고 나온 후 다시 킨건데 그게 오류의 원인이 된다니(…) 앞으로는 잘 껐더라도 조심조심(?) 켜자.(…)

우선 stop-all.sh 으로 하둡을 끈다. 터미널에서 hadoop namenode -format 을 쳐서 네임 노드를 초기화시킨 후, start-all.sh로 하둡을 재기동한다.

3. jps를 쳤을 때 Datanode 올라오지 않는 경우 해결

여러가지 이유가 있다. 우선 stop-all.sh 으로 하둡을 끈다.

데이터를 저장하는 대상 폴더(사람마다 이름을 다르게 지정했을 테지만 보통 data, temp 등)들를 다 지우고, 해당 폴더들을 다시 생성한 후 start-all.sh로 다시 기동하면 된다.

4. 기타 문제들 : 로그 파일을 통한 해결 

앞서와 같은 방법으로 해도 문제가 해결되지 않을 수 있다. 가장 좋은 방법을 로그를 보고 해결하는 것이다.

하둡 기동시에(start-all.sh 를 입력했을 때) 보통 아래와 같이 로그 파일에 대한 정보가  나온다.

starting namenode, logging to /usr/local/hadoop-1.2.1/logs/hadoop-sist-namenode-sist.out
localhost: starting datanode, logging to /usr/local/hadoop-1.2.1/logs/hadoop-sist-datanode-sist.out
localhost: starting secondarynamenode, logging to /usr/local/hadoop-1.2.1/logs/hadoop-sist-secondarynamenode-sist.out
starting jobtracker, logging to /usr/local/hadoop-1.2.1/logs/hadoop-sist-jobtracker-sist.out
localhost: starting tasktracker, logging to /usr/local/hadoop-1.2.1/logs/hadoop-sist-tasktracker-sist.out

이 후 jps를 쳐서 datanode가 뜨지 않았다면 cat을 이용해 해당 로그 파일을 읽으면 된다. 단, out확장자가 아니라 log 확장자의 파일을 봐야 한다.

그러니까 cat /usr/local/hadoop-1.2.1/logs/hadoop-sist-datanode-sist.out 이 아니라, cat /usr/local/hadoop-1.2.1/logs/hadoop-sist-datanode-sist.log 라고 치면 된다.

로그에 떨어지는 대표적인 상황 몇 개를 보자.


4-1. 네임스페이스 아이디 불일치 

2016-06-18 10:18:49,167 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Incompatible namespaceIDs in /home/hadoop/hdfs/data: namenode namespaceID = 1686483618; datanode namespaceID = 178888247

현재 네임노드의 네임스페이스 아이디와 데이터노드의 네임스페이스 아이디가 일치하지 않는다고 나오고 있다. 이 때는 (1)하둡 종료(stop-all.sh) (2)작업대상 폴더들 삭제하고 다시 생성(rm명령어, mkdir명령어) (3)네임노드 초기화(hadoop namenode -format) (4)하둡 재기동(start-all.sh) 순으로 진행하면 된다.

네임노드 초기화시에 네임스페이스 아이디를 서로 맞춰준다.

4-2. 권한 문제

2016-06-18 11:08:07,832 WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Invalid directory in dfs.data.dir: Incorrect permission for /home/hadoop/hdfs/data, expected: rwxr-xr-x, while actual: rwxrwxrwx
2016-06-18 11:08:07,832 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: All directories in dfs.data.dir are invalid.

작업대상 폴더들의 권한을 ( data, name, mapred, temp) 755 로 줘야 하는 문제다. 해당 폴더경로로 이동해서 chmod 755 * 을 주면 된다. 권한이 너무 높아도 안되고(777) 너무 낮아도 안되는 것 같다.