반응형

우편번호는 아래 링크 사이트를 통해 최신 데이터를 받을 수 있습니다.

 

https://www.epost.go.kr/search/zipcode/cmzcd002k01.jsp

 

우편번호 DB와 검색기 소개 - 우편번호 안내

우편번호 검색기란? 우편번호 검색기 바로가기 ※ 우편번호를 검색하거나 고객이 보유한 다량의 주소록에 올바른 우편번호를 자동으로 생성해 주는 프로그램입니다.

www.epost.go.kr

 

1. 테이블 생성

 

ZIPDB라는 우편번호를 저장할 수 있는 테이블을 생성합니다.

 

저는 데이터베이스를 TEST라는 곳에서 아래 테이블을 생성하였습니다.

 

CREATE TABLE IF NOT EXISTS ZIPDB (
ZONE_NO VARCHAR(5) not null COMMENT '구역번호(우편번호)', 
CTPRVN VARCHAR(20) COMMENT '시도', 
CTPRVN_ENG VARCHAR(40) COMMENT '시도영문', 
SIGNGU VARCHAR(20) COMMENT '시군구', 
SIGNGU_ENG VARCHAR(40) COMMENT '시군구영문', 
EUP_MYEON VARCHAR(20) COMMENT '읍면', 
EUP_MYEON_ENG VARCHAR(40) COMMENT '읍면영문', 
RN_CODE VARCHAR(12) COMMENT '도로명코드', 
RN VARCHAR(80) COMMENT '도로명', 
RN_ENG VARCHAR(80) COMMENT '도로명영문', 
UNDGRND_AT VARCHAR(1) COMMENT '지하여부(0:지상, 1:지하)', 
BDNBR_MNNM INT(5) COMMENT '건물번호본번', 
BDNBR_DUCA INT(5) COMMENT '건물번호부번', 
BULD_MANAGE_NO VARCHAR(25) COMMENT '건물관리번호', 
MUCH_DLVR_OFFIC_NM VARCHAR(40) COMMENT '다량배달처명(null)', 
SIGNGU_BDNBR_NM VARCHAR(200) COMMENT '시군구용건물명', 
LEGALDONG_CODE VARCHAR(10) COMMENT '법정동코드', 
LEGALDONG_NM VARCHAR(20) COMMENT '법정동명', 
LI_NM VARCHAR(20) COMMENT '리명', 
ADSTRD_NM VARCHAR(40) COMMENT '행정동명', 
MNTN_AT VARCHAR(1) COMMENT '산여부(0:토지, 1:산)', 
LNM_MNNM INT(4) COMMENT '지번본번', 
EMD_SN VARCHAR(2) COMMENT '읍면동일련번호', 
LNM_DUCA INT(4) COMMENT '지번부번', 
OLD_ZIP VARCHAR(6) COMMENT '구 우편번호(null)', 
ZIP_SN VARCHAR(3) COMMENT '우편번호일련번호(null)'

 ENGINE = INNODB 
 DEFAULT CHARSET=utf8
 ;

 

 -- 인덱스 (구역번호 5자리 신 우편번호)
CREATE INDEX ZIPDB_IX1 ON zipdb(ZONE_NO);

-- 인덱스 (시도,시군구,읍면)
CREATE INDEX ZIPDB_IX2 ON zipdb(CTPRVN, SIGNGU, EUP_MYEON);

-- 인덱스(도로명코드)
CREATE INDEX ZIPDB_IX3 ON zipdb(RN_CODE);

-- 인덱스 (도로명)
CREATE INDEX ZIPDB_IX4 ON zipdb(RN);

 

 

2. 데이터 로드
우편번호 사이트의 모든 zip 값들을 서버에 /tmp/zip 폴더에 업로드
다만! 파일을 반드시 utf8로 변경 합니다.(메모장 열고 다른이름 저장에서 UTF8로 지정하면 됨.)

 

실행한 MariaDB는 10.3 버전으로 약간의 문법이 다릅니다.

 

다음 명령을 실행하여 LOAD DATA 문장을 자동으로 만듭니다.

 

# ls -lsa /tmp/zip/*.txt | awk '{print "LOAD DATA INFILE " "\x27" $10 "\x27" " INTO TABLE ZIPDB character set " "\x27" "utf8" "\x27" " fields terminated by " "\x27" "|" "\x27" " IGNORE 1 LINES;"}' 

 

아래 문장은 root 계정으로 local 시스템에 TEST 데이터베이스에 접속하라는 의미입니다.

# mysql -u root -p --local-infile=1 TEST (접속) 

 

MariaDB [TEST]> LOAD DATA INFILE '/tmp/zip/강원도.txt' INTO TABLE ZIPDB character set 'utf8' fields terminated by '|' IGNORE 1 LINES; 

 

위와 같이 수행하면 아래 그림과 같이 오류가 없는 경우 Query OK와 함께 Insert된 수가 출력됩니다.

 

2019.11.01 일 데이터 기준으로 약 1.3GB의 용량이 입력됩니다.

건수 : 3,112,960 건 

 

 

 

반응형
반응형

3. package와 import

   

3.1 패키지(package)


패키지란, 클래스의 묶음이다. 패키지에는 클래스 또는 인터페이스를 포함 시킬 수 있으며, 서로 관련된 클래스들끼리 그룹 단위로 나누어 놓음으로써 클래스를 효율적으로 관리할 수 있다.
또한 같은 이름의 클래스 일지라도 서로 다른 패키지에 존재하는 것이 가능하므로, 자신만의 패키지 체계를 유지함으로써 다른 개발자가 개발한 클래스 라이브러리의 클래스와 이름이 충돌하는 것을 피할 수 있다.
지금까지는 단순히 클래스명으로만 클래스를 구분 했지만 클래스의 실제 이름(full name)은 패키지명을 포함한 것이다. 예를 들면, String클래스의 패키지명을 포함한 이름은 java.lang.String이다. 즉, java.lang패키지에 속한 String클래스라는 의미이다. 그래서 같은 이름의 클래스일 지라도 서로 다른 패키지에 속하면 패키지명으로 구별이 가능하다.
클래스가 물리적으로 하나의 클래스파일(.class)인 것과 같이 패키지는 물리적으로 하나의 디렉토리이다. 그래서 어떤 패키지에 속한 클래스는 해당 디렉토리에 존재하는 클래스파일(.class)이어야 한다.

예를 들어, java.lang.String클래스는 물리적으로 디렉토리 java의 서브디렉토리인 lang에 속한 String.class파일이다. 그리고 우리가 자주 사용하는 System클래스 역시 java.lang패키지에 속하므로 lang디렉토리에 포함되어 있다.







String클래스는 rt.jar파일에 압축되어 있으며 아래의 그림은 압축을 풀기 전과 후의 그림이다. 클래스와 관련 파일들을 압축한 것이 jar파일(*.jar)이며, jar파일은 jar.exe이외에 알집이나 winzip으로 압축을 풀 수 있다.



디렉토리가 하위디렉토리를 가질 수 있는 것처럼, 패키지도 다른 패키지를 포함할 수 있으며 점(.)으로 구분한다. 예를 들면 java.lang패키지에서 lang패키지는 java패키지의 하위패키지이다.


- 하나의 소스파일에는 첫 번째 문장으로 단 한번의 패키지 선언을 허용한다.
- 모든 클래스는 반드시 하나의 패키지에 속해야한다.
- 패키지는 점(.)을 구분자로 하여 계층구조로 구성할 수 있다.
- 패키지는 물리적으로 클래스 파일(.class)을 포함하는 하나의 디렉토리이다.





3.2 패키지의 선언

패키지를 선언하는 것은 아주 간단하다. 클래스나 인터페이스의 소스파일(.java)에서 다음과 같이 한 줄만 적어주면 된다.


package 패키지명;



위와 같은 패키지 선언문은 반드시 소스파일에서 주석과 공백을 제외한 첫 번째 문장이어야 하며, 하나의 소스파일에 단 한번만 선언될 수 있다. 해당 소스파일에 포함된 모든 클래스나 인터페이스는 선언된 패키지에 속하게 된다.
패키지명은 대소문자를 모두 허용하지만, 클래스명과 쉽게 구분하기 하기위해서 소문자로 하는 것을 원칙으로 하고 있다.

모든 클래스는 반드시 하나의 패키지에 포함되어야 한다고 했다. 그럼에도 불구하고 지금까지 소스파일을 작성할 때 패키지를 선언하지 않고도 아무런 문제가 없었던 이유는 자바에서 기본적으로 제공하는 '이름없는 패키지(unnamed package)' 때문이다.

소스파일에 자신이 속할 패키지를 지정하지 않은 클래스는 자동적으로 '이름 없는 패키지'에 속하게 된다. 결국 패키지를 지정하지 않는 모든 클래스들은 같은 패키지에 속하는 셈이 된다.
간단한 프로그램이나 애플릿은 패키지를 지정하지 않아도 별 문제 없지만, 큰 프로젝트나 Java API와 같은 클래스 라이브러리를 작성하는 경우에는 미리 패키지를 구성하여 적용하도록 한다.

[예제7-9] PackageTest.java

package com.javachobo.book;

class PackageTest
{
      public static void main(String[] args)
      {
            System.out.println("Hello World!");
      }
}

위의 예제를 작성한 뒤 다음과 같이 '-d' 옵션을 추가하여 컴파일을 한다.


C:\j2sdk1.4.1\work>javac -d . PackageTest.java


'-d'옵션은 소스파일에 지정된 경로를 통해 패키지의 위치를 찾아서 클래스파일을 생성한다. 만일 지정된 패키지와 일치하는 디렉토리가 존재하지 않는다면 자동적으로 생성한다.
'-d'옵션 뒤에는 해당 패키지의 루트(root)디렉토리의 경로를 적어준다. 여기서는 현재디렉토리(.) 즉, 'C:\j2sdk1.4.1\work' 로 지정했기 때문에 컴파일을 수행하고 나면 다음과 같은 구조로 디렉토리가 생성된다.



기존에 디렉토리가 존재하지 않았으므로 컴파일러가 패키지의 계층구조에 맞게 새로 디렉토리를 생성하고 컴파일된 클래스파일(PackageTest.class)를 book디렉토리에 놓았다.

[참고] 만일 '-d'옵션을 사용하지 않으면, 프로그래머가 직접 패키지의 계층구조에 맞게 디렉토리를 생성해야한다.

이제는 패키지의 루트 디렉토리를 클래스패스(classpath)에 포함시켜야 한다. com.javachobo.book패키지의 루트 디렉토리는 디렉토리 'com'의 상위 디렉토리인 'C:\j2sdk1.4.1\work'이다. 이 디렉토리를 클래스패스에 포함시켜야만 실행 시 JVM이 PackageTest클래스를 찾을 수 있다.
[참고]클래스패스는 컴파일러(javac.exe)나 JVM 등이 클래스의 위치를 찾는데 사용되는 경로이다.

Windows 98이하에서는 autoexec.bat파일에 다음과 같은 명령을 한 줄 추가하면 된다.


SET CLASSPATH=.;C:\j2sdk1.4.1\work;


Windows 2000에서는 '시스템등록정보-고급-환경변수-새로만들기'를 통해 아래의 그림과 같이 설정해 준다.



';'를 구분자로 하여 여러 개의 경로를 클래스패스에 지정할 수 있으며, 맨 앞에 '.;'를 추가한 이유는 현재 디렉토리(.)를 클래스패스에 포함시키기 위해서이다.
클래스패스를 지정해 주지 않으면 기본적으로 현재 디렉토리(.)가 클래스패스로 지정되지만, 이처럼 클래스패스를 따로 지정해주는 경우에는 더 이상 현재 디렉토리가 자동적으로 클래스패스로 지정되지 않기 때문에 이처럼 별도로 추가를 해주어야 한다.
jar파일을 클래스패스에 추가하기 위해서는 경로와 파일명을 적어주어야 한다. 예를 들어 C:\j2sdk1.4.1\work\util.jar파일을 클래스패스에 포함시키려면 다음과 같이 한다.

SET CLASSPATH=.;C:\j2sdk1.4.1\work;C:\j2sdk1.4.1\work\util.jar;

이제 클래스패스가 바르게 설정되었는지 확인하기 위해 다음과 같은 명령어를 입력해보자.


C:\WINDOWS>echo %classpath%
.;C:\j2sdk1.4.1\work;


현재 디렉토리를 의미하는 '.'와 'C:\j2sdk1.4.1\work'가 클래스패스로 잘 지정되었음을 알 수 있다. 자, 이제 PackageTest예제를 실행시켜보자.

[실행결과]
C:\WINDOWS>java com.javachobo.book.PackageTest
Hello World!

실행 시에는 이와 같이 PackageTest클래스의 패키지명을 모두 적어주어야 한다.

J2SDK에 기본적으로 설정되어 있는 클래스패스를 이용하면 위의 예제에서와 같이 클래스패스를 따로 설정하지 않아도 된다. 새로 추가하고자 하는 클래스를 'J2SDK설치디렉토리\jre\classes'디렉토리에, jar파일인 경우에는 'J2SDK설치디렉토리\jre\lib\ext'디렉토리에 넣기만 하면 된다.

[참고] jre디렉토리 아래의 classes디렉토리는 J2SDK설치 시에 자동으로 생성되지 않으므로 사용자가 직접 생성해야한다.

또는 실행 시에 '-cp'옵션을 이용해서 일시적으로 클래스패스를 지정해 줄 수도 있다.

C:\WINDOWS>java -cp c:\j2sdk1.4.1\work com.javachobo.book.PackageTest



3.3 import문

소스코드를 작성할 때 다른 패키지의 클래스를 사용할 때는 패키지명이 포함된 이름을 사용해야한다. 하지만, 매번 패키지명을 붙여서 작성하기란 여간 불편한 일이 아닐 것이다.
클래스의 코드를 작성하기 전에 import문으로 사용하고자 하는 클래스의 패키지를 미리 명시해주면 소스코드에 사용되는 클래스이름에서 패키지명은 생략할 수 있다.

import문의 역할은 컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공하는 것이다. 컴파일 시에 컴파일러는 import문을 통해 소스파일에 사용된 클래스들의 패키지를 알아 낸 다음, 모든 클래스이름 앞에 패키지명을 붙여 준다.

[참고] import문은 프로그램의 성능에 전혀 영향을 미치지 않는다. import문을 많이 사용하면 컴파일 시간이 아주 조금 더 걸릴 뿐이다.



3.4 import문의 선언

모든 소스파일(.java)에서 import문은 package문 다음에, 그리고 클래스 선언 문 이전에 위치해야한다. 그리고 import문은 package문과는 달리 한 소스파일에 여러 번 선언할 수 있다.


일반적인 소스파일의 구성은 'package문-import문-클래스선언'의 순서로 되어 있다.


import문을 선언하는 방법은 다음과 같다.


import 패키지명.클래스명;
또는
import 패키지명.*;


키워드import와 패키지명을 생략하고자 하는 클래스의 이름을 패키지명과 함께 써주면 된다. 같은 패키지에서 여러 개의 클래스가 사용될 때, import문을 여러 번 사용하는 대신 '패키지명.*'을 이용해서 지정된 패키지에 속하는 모든 클래스를 패키지명 없이 사용할 수 있다.
[참고] 클래스이름을 지정해주는 대신 '*'을 사용하면, 컴파일러는 해당 패키지에서 일치하는 클래스이름을 찾아야 하는 수고를 더 해야 할 것이다. 단지 그 뿐이다. 다른 차이는 없다.


import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;


이처럼 import문을 여러 번 사용하는 대신


import java.util.*;


위와 같이 한 문장으로 처리할 수 있다. 한 패키지에서 여러 클래스를 사용하는 경우 클래스의 이름을 일일이 지정해주는 것보다 '패키지명.*'과 같이 하는 것이 편리하다.

하지만, import하는 패키지의 수가 많을 때는 어느 클래스가 어느 패키지에 속하는지 구별하기 어렵다는 단점이 있다.
한가지 더 알아두어야 할 것은 import문에서 클래스의 이름 대신 '*'을 사용하는 것이 하위 패키지의 클래스까지 포함하는 것은 아니라는 것이다.


import java.util.*;
import java.text.*;


그래서, 위의 두 문장 대신 다음과 같이 할 수는 없다.


import java.*;


[예제7-10] ImportTest.java

import java.text.SimpleDateFormat;
import java.util.Date;

class ImportTest
{
      public static void main(String[] args)
      {
            Date today = new Date();
           
            SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
            SimpleDateFormat time = new SimpleDateFormat("hh:mm:ss a");

            System.out.println("오늘 날짜는 " + date.format(today));
            System.out.println("현재 시간은 " + time.format(today));
      }
}
[실행결과]
오늘 날짜는 2003/01/07
현재 시간은 01:59:53 오후

현재 날짜와 시간을 지정된 형식에 맞춰 출력하는 예제이다. SimpleDateFormat과 Date클래스는 다른 패키지에 속한 클래스이므로 import문으로 어느 패키지에 속하는 클래스인지 명시해 주었다. 그래서 소스에서 클래스이름 앞에 패키지명을 생략할 수 있었다.
만일 import문을 지정하지 않았다면 다음과 같이 클래스이름에 패키지명도 적어줘야 했을 것이다.


java.util.Date today = new java.util.Date();
           
java.text.SimpleDateFormat date = new java.text.SimpleDateFormat("yyyy/MM/dd");
java.text.SimpleDateFormat time = new java.text.SimpleDateFormat("hh:mm:ss a");


import문으로 패키지를 지정하지 않으면 위와 같이 '이름없는 패키지'에 속한 클래스를 제외한 모든 클래스이름 앞에 패키지명을 반드시 붙여야 한다.
지금까지 System과 String 같은 java.lang패키지의 클래스들을 패키지명 없이 사용할 수 있었던 이유는 모든 소스파일에는 묵시적으로 다음과 같은 import문이 선언되어 있기 때문이다.


import java.lang.*;


java.lang패키지에는 매우 빈번히 사용되는 중요한 클래스들이 속한 패키지이기 때문에 따로 import문으로 지정하지 않아도 되도록 한 것이다.

 

출처 : http://kin.naver.com/open100/db_detail.php?d1id=1&dir_id=10106&eid=PRkOvR1lMBu/xAgOgb4ka1KrOj9CeukU

반응형

+ Recent posts