GeoService-Xr의 SQL 실행 서비스

GeoService-Xr은 연결된 DBMS에 대해 SQL문 실행을 대신해 주고 그 결과를 클라이언트에게 JSON 형식으로 전송해 주는 기능을 제공합니다. 이를 위해서 실행할 SQL 문이 정의된 파일이 서버측에 필요한데요. 아래는 그 한가지 예입니다.

{
    "metadata": {
        "startToken": "{$",
        "endToken": "}"
    },
	
    "sql": {
        "getLayers": "SELECT layers FROM core_users LIMIT 1",
        "getBuildingsByRoadCode": "SELECT ST_AsText(the_geom) FROM buld_a WHERE rn_cd ='{$road_cd}' LIMIT 1",
        "addUseLog": "INSERT INTO core_uselog (systemname, username) VALUES('{$systemName}', '{$userName}')" 	
    }
}

위의 내용에 규칙이 존재하는데요. sql 문의 id가 get으로 시작하는 getLayers나 getBuildingsByRoadCode는 반드시 SELECT 문이여야 하고, add로 시작한다면 INSERT 문, del로 시작하면 DELETE 문, set으로 시작하면 UPDATE 문이어야 합니다. 위의 SQL 정의 파일의 이름이 SQL.json이라고 한다면, GeoService-Xr의 환경설정 파일인 XrConfig.xml에 다음처럼 기술되어져야 GeoService-Xr이 실행될때 SQL 문이 로딩되어 실행할 준비가 완료됩니다..


    ....

    d:/config/SQL.json

위와 같은 준비가 되면, 클라이언트 측에서 SQL 문을 호출할 수 있는데요. 아래는 javascript 문을 통해 실행한 내용의 예입니다.

var road_cd = this._CodeMap_Road[name];

$.ajax({
    url: url = ConfigValues.GIS_SERVER + "/Xr?rsql|getBuildingsByRoadCode|" + ConfigValues.DB_NAME,
    type: "POST",
    crossDomain: true,
    data: "road_cd:=" + road_cd + "\nparam2:=param2", // 파라메터의 구분은 \n 문자로 함
    dataType: "text",
    success: function (response) {
        // Java, C/C++ 등과 같은 언어의 편의성을 위해 결과의 끝에 \0이 붙음
        // javascript에서 json으로 파싱하기 위해 response 문자열 끝에 \0 문자를 제거해야 함
        response = response.substr(0, response.length - 1); 
        response = JSON.parse(response);
        
        ...
    },

    error: function (xhr, status) {
        alert("ERROR");
    }
});

GeoService-Xr에서 MIME Type 설정하기

MIME 타입은 서버측에서 클라이언트로 전송한 리소스(문서)의 종류가 무엇인지를 나타내는 방법입니다. 클라이언트는 대부분 IE, Chrome 등과 같은 웹브라우저인데요. 서버측으로 받는 리소스가 어떤 종류인지를 정확히 파악해야만 이 리소스를 어떻게 처리할지 판단할 수 있고, 이런 경우에 MIME Type을 사용합니다.

참고로 MIME 타입을 사용하지 않고 해당 리소스의 종류를 파악하기 위한 방법은 리소스 이름의 접미사나 리소스의 실제 내용의 헤더 부분에 그 종류를 파악할 수 있는 정보가 있습니다면, 모든 리소스가 이런 규칙을 사용하지도 않으므로 결국 MIME 타입이 가장 표준이 되는 리소스의 종류를 파악할 수 있는 수단이 됩니다.

GeoService-Xr에서는 공간 데이터를 포함하여 다양한 리소스를 클라이언트로 서비스해주는데요. 서버가 가지고 있는 파일에 대한 MIME Type을 지정하기 위한 방식을 정리해 봅니다.

아래는 서비스하고자 하는 파일의 확장자를 통해 MIME Type을 지정하는 하나의 예로 hwp와 pptx를 확장자로 갖는 파일에 대한 MimeType을 지정하고 있습니다.


    
        
            hwp
            application/octet-stream
         
        
            pptx
            application/octet-stream
        
    

위의 경우라면 hwp와 pptx에 대한 클라이언트 측의 행동은 일반적인 다운로드로써 해당 리소스를 파일로 저장하도록 유도합니다. 위의 정보는 GeoService-Xr의 Web 디렉토리에 XrConfig.xml 파일로 존재해야 합니다.

[Java] 오늘 날짜, 어제 날짜

Java에서 오늘 날짜를 구하기 위한 코드입니다. 집계 서비스를 만들기 위해 사용한 코드인데요.

GregorianCalendar today = new GregorianCalendar();

int Year = today.get(Calendar.YEAR);
int Month = today.get(Calendar.MONTH);
int Date = today.get(Calendar.DATE);
int Hour = today.get(Calendar.HOUR_OF_DAY);

GregorianCalendar 클래스를 생성할 때 파라메터를 주지 않으면 오늘 날짜에 대한 객체가 생성됩니다. 주의할 점은 GregorianCalendar의 1월을 0부터 시작하므로, 필요시에 월의 값에 1을 더해줘야 합니다.

참고로 get 매서드에서 사용할 수 있는, 각 시간의 단위를 얻기 위해서 사용할 수 있는 값은 다음과 같습니다.

  • Calendar.YEAR – 년도
  • Calendar.MONTH – 월(0~11)
  • Calendar.DATE – 일
  • Calendar.AP_PM – 오전/오후
  • Calendar.HOUR – 시
  • Calendar.MINUTE – 분
  • Calendar.SECODE – 초

이제 여기서 한단계 더 나아가.. 어제는? 한달전은? 일주일전은? 어떻게 알 수 있을까.. 아래의 코드는 위의 today를 기준으로 1일 전을 나타내는 코드입니다.

today.add(Calendar.DAY_OF_MONTH, -1);

위의 코드를 이용하면 특정 날짜를 기준으로 원하는 날짜를 정확하게 파악할 수 있을 것입니다. GregorianCalendar 에서 기본적으로 사용하는 TimeZone은 OS에서 설정된 나라로 지정됩니다. 이 TimeZone은 setTimeZone 매서드를 통해 재변경이 가능합니다. 아래의 코드는 Europe/London에 대한 TimeZone으로 변경하는 코드 예입니다.

TimeZone timeZone = TimeZone.getTimeZone("Europe/London");
today.setTimeZone(timeZone);

끝으로 GregorianCalendar 객체의 시간을 다양하게 표현하기 위해 SimpleDateFormat 클래스를 사용할 수도 있습니다. 아래의 코드는 SimpleDateFormat 클래스르 사용해 원하는 형식으로 시간을 표현하는 코드 예입니다.

GregorianCalendar today = new GregorianCalendar();
SimpleDateFormat format = new SimpleDateFormat("yyyy년 MM월 dd일 aa hh시 mm분 ss초");
String strTime = format.format(today.getTime());

Oracle 12c 설치 후 계정 생성 및 JDBC 연결 테스트

오라클 12c(12.2.0.1.0)을 설치하고 계정을 생성하고 필요한 권한을 부여한 후 테이블을 생성해 몇가지 데이터를 INSERT해서 최종적으로 JDBC로 연결해 쿼리를 날려 데이터를 받는 테스트를 하고 몇가지 내용을 정리합니다. 참고로 오라클 12c에는 기본적으로 공간 데이터 처리를 위한 기능이 같이 설치가 됩니다.

오라클을 설치하고 다음 명령을 통해 계정을 생성하고 해당 계정에 필요한 권한을 부여합니다. Console 창에서 실행한 경우입니다.

# sys 계정으로 접속
sqlplus / as sysdba

# 계정 생성(로컬 사용자가 아닌 공통 사용자 생성의 경우 반드시 c##을 붙여줘야 함)
create user c##dip2k identified by PASSWORD;

# 계정 잠근 해제
alter user c##dip2k account unlock;

# 로그인 및 테이블 생성 권한 부여
grant connect, resource to c##dip2k

# Tablespace 권한 부여(INSERT 문 실행 가능하도록 함)
alter user c##dip2k default tablespace users quota unlimited on users;

이제 다시 sqlplus를 실행해 앞서 생성한 계정으로 로그인하고 test_mytable이라는 이름의 테이블을 생성하고 데이터를 추가합니다. 그리고 오라클용 JDBC jar 파일을 다운로드 받고 다음 java 코드를 통해 연결을 테스트합니다.

package test_oracle_jdbc;

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

public class MainEntry {
    public static void main(String[] args) {
        String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        String USER = "c##dip2k";
        String PASSWORD = "PASSWORD";
        String query = "SELECT * from test_mytable";
		
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
		
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
			
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            stmt = conn.createStatement();
            rs = stmt.executeQuery(query);
			
            while(rs.next()) {
                String v = rs.getString(1);
				
                System.out.println(v);
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(conn != null) conn.close();
            } catch(SQLException e) {}
        }
    }
}