jVectorMap은 친절히 맵의 Projection을 지원한다. 

국제 표준에 해당하는 Shape 파일을 jVectorMap Converter를 이용할 경우 map projection이 동일하게 변환되지만
한국 지도 행정동 2단계 지도를 변환해 보니 지도 군데 군데 구멍이 뚫리게 되어 이를 사용할 수 없게 되었다. 

관련 글 : http://www.yeory.com/270

 
이 때문에 완벽한 지도를 보여주어야 하기 때문에 QGIS를 이용하여 SVG로 변환하여 지도를 표시하였다.
이 경우 지도는 모두 나오는데 지도 타입(Projection)이 위/경도를 사용할 수 없기 때문에 위/경도로 좌표를 표시할 수 없다.

필요한 것은.... 
  • 지도의 가로 세로 -> 지도 자체의 가로, 세로 사이즈
    (div 등 jVectorMap을 이용하여 그려주는 태그의 사이즈가 아니다.)

  • 지도의 상하좌우 한계점의 위/경도 총 4개
    이 한계점 정보가 정확하지 않으면 X, Y 변환 값이 모두 틀어진다.

이 모든 정보들은 SHP -> SVG로 추출할 때 사용하는 QGIS SVG 플러그인에서 설정이 가능한 정보들이다.

작업 순서는 아래 그림처럼...

< 지도의 가로-세로 사이즈 설정 >

< 가로-세로 설정에 의해 틀어진 지도를 중앙에 위치하도록 설정 >

< 중앙에 맞춰진 지도의 각 상하좌우 위/경도를 설정해 주어야 한다>

마지막 이미지에서 보여지는 정보들이 스크립트에 설정해주어야 하는 정보이다.... 

maxY -> northLat
minY -> southLat
maxX -> eastLong
minY -> westLong

필요한 것이 나왔다면 아래 함수를 이용해 X, Y 변환이 가능하다.
	function convert(latitude, longitude) {
		// lat : 위도, long : 경도
		
		// QGIS > SVG 플러그인 속성에 적은 가로-세로
		var width = 792;
		var height = 611;

		// QGIS > SVG 플러그인 속성에서 SET 된 각 한계선
		var eastLong = 131.754044;		// 우측 한계선
		var westLong = 124.268181;		// 좌측 한계선
		var northLat = 38.749657;		// 상측 한계선
		var southLat = 32.974579;		// 하측 한계선
		
		// 경도 -> x
		var longDiff = eastLong - westLong;
		var lon = (longitude - westLong) * (width / longDiff);
		
		// 위도 -> y
		var latDiff = northLat - southLat;
		var lat = (northLat - latitude) * (height / latDiff);
		
		return [ lon, lat];
	}
경도 1도에 해당하는 픽셀을 구하고... (지도 넓이 / (좌-우)) 표시하고자 하는 경도를 좌측 값으로부터 뺀 후 곱하면 된다. 


모서리에 있는 점은 지도 가로-세로를 표시한 것이고, 위/경도는 이 안쪽을 기준으로 변환이 되어야만 한다.



하루 삽질했으나 원하는 결과가 나왔으니 만족...



업무 상 추세선을 그려야한다.

기존에 사용하던 유료 컴퍼넌트는 추세선을 그려주지 않는다..
(대체 이딴걸 돈주고 사용하는 이유가 뭘까..?)

 유료 컴퍼넌트를 대체하기 위해 찾은 2개의 차트 중에... 

Flot 차트의 플러그인으로 추세선을 그려주는 플러그인이 존재한다. 

jQuery.flot.trendline.js

한번 작업해보고.. 다시 포스팅...



추세선을 그렸다...

기존 플러그인을 조금 수정했는데 기존에는 From - To 형식으로 추세선을 그린다.

보다 정확히 그리고자 데이터 개수와 추세선 값을 1:1로 대응시켜 추세선을 그리게끔 변경하였다.


다운로드 : jquery.flot.trendline.js 

Full Source Download : trendLineChart

아래는 추세선을 표시한 차트 샘플이다.




'Web > Flot Chart' 카테고리의 다른 글

Flot 차트에 추세선(trend line) ??  (0) 2013.07.29
ExtJS에서 컴퍼넌트를 만들어 쓴다고 했을때 크게 3가지의 방법이 존재한다. 

그 중에 가장 많이 쓰는 2개의 차이점을 간략하게 적어 놓는다.

 
Ext.widget  
  이를 사용하게 될 경우 기존에 존재하는 컴퍼넌트의 인스턴스 쿼리를 반환하지 않는다. 
  즉 내가 만드는 컴퍼넌트가 다른 방법(create, define)으로 만들어져 있더라도 가져오지도 않고,
  새로 만들지만 다른 곳에서 찾아서 쓸 수 있는 쿼리를 리턴하지 않는 다는 것..
  
Ext.create
  이를 사용하게 될 경우 항상 해당 xtype의 인스턴스로 새로이 생성한다.
  생성과 함께 인스턴스를 찾아 쓸 수 있도록 쿼리가 만들어진다.
  만약 같은 컴퍼넌트를 각각 10곳에서 create 했다면 이론적으로 10개의 인스턴스가 존재하게 되는 것.


무조건 widget만 쓰는것도 안좋고, 그렇다고 create만 죽어라 하는 것도 좋지 않다.

하나의 폼을 10개의 화면에서 사용을 한다면..? 
10개의 화면에서 모두 create를 할것인가..? 아니면 widget을 할 것인가?? 

create와 widget은 임시, 1회용 또는 동적으로 폼의 형태를 변형할 경우에 적합하다고 생각해본다.

아니면 말고 

'Web > extjs4' 카테고리의 다른 글

Ext.create() and Ext.widget() 의 차이점...  (0) 2013.07.26
Ext.Ajax  (0) 2013.07.22
extjs grid 헤더 통합 및 하단 합계 추가.  (0) 2012.04.27
extjs grid dataStore onLoad 처리.  (0) 2012.04.24
extjs grid double click event  (0) 2012.04.23
extjs grid 헤더와 컬럼 따로 정렬하기  (0) 2012.04.23
jVectorMap은 자체적으로 convert를 사용하여 shp 파일의 vector 이미지를 svg로 변환하여 맵 파일을 생성한다.

그러나 이 컨버터를 이용할 경우 svg 변환 상에 오류가 있는것인지 대한민국 지도 상에 구멍이 슝슝 뚫린다.

아래처럼... 


대구와 대전 일부가 없다.

이를 해결하기 위해 제작자에게 메일도 보냈지만 묵묵부답이라 자체적으로 해결 할 수 밖에... 

1. shp 파일을 편집할 수 있는 (읽어 들일 수 있는)  프로그램을 찾는다.
2. 이 프로그램을 이용하여 SVG로 변환할 수 있는지 찾는다.
3. SVG로 변환된 정보를 svgto.jvectormap.com 에서 지도로 변환해 본다.

간단한거 같지만 이게 은근 쉽지가 않았다..
개발자로써 지도 프로그램을 쓰는 것도 그렇고 사용법을 일일이 찾아야 하므로... 

첫번째 사용했던 프로그램 FME Desktop 2013 이란 상용 프로그램이다.

14일간의 트라이얼을 기대하고 설치 했는데... 트라이얼 코드를 웹사이트에 접속해서 등록해야만 코드가 발급된다. ;;
여튼, 이 프로그램으로 좋은 것은.. SHP 파일을 정말 자세하게 까(?) 볼 수 있었다.

  1. FME Data Inspector

    shp 파일은 벡터 정보와 데이터 셋을 같이 가지고 있다. data inspector는 이 데이터 셋을 집중적으로 깔 수 있는 툴이다.

    아래 이미지는 data inspector를 이용하여 kor_adm2.shp 파일을 열었을때의 화면..



  2. FME Universal Viewer
    이 툴은 shp 파일의 벡터 부분을 집중적으로 깔 수 있다. 라인과, 포인트, 텍스트, 채우기 색깔등을 볼 수 있는 것.
    그리고 각 조각을 선택하면 그에 대한 정보를 보여준다. (사실 inspector와 거의 같은 정보..)
    이미지는 생략하고..

    이 툴을 이용해서 shp -> svg로 변환이 가능하다.
    shp가 그린 벡터 조각이 가진 어트리뷰터를 모드 svg path 태그안의 어트리뷰트로 변환이 된다.

    그런데!! 이걸 svgto.jvectormap.com 에서 지도로 변환해보면 지도가 안나온다.

    왜인지 모르겠는데 안나온다...

     
  3. FME Workbench
    이 툴은 전문가 적인 작업이 가능하다.

    내가 불러들여 작업할 파일을 설정하는데 이를 Reader라 하고
    어떤식으로 변환할 것인지를 설정해야하는데 이를 Writer라고 부른다.

    아래는 이에 대한 이미지..


    이렇게 리더와 Writer를 설정하고 OK 누르면 아래 이미지와 같은게 나온다..


    Writer 쪽 ... 을 눌러보면 User Attribute 탭 에서 내가 추출하고자 하는 Reader의 Attribute를 지정할 수 있다.
    Reader와 같은 이름을 지정해야만 SVG로 변환 할 시 나타나며 이름이 틀릴경우 나타나지 않는다.



    대충 설정을 하고 Shift + F5 를 누르게 되면 Reader -> Writer로 변환을 하게 되는데 jVectorMap으로 안나온다.

     
FME Desktop 2013 결론은 jVectorMap에서 사용하는 SVG를 추출할 수 없다.

내가 못하는 거 일 수 있지만 안된다.  그래서 다음 프로그램으로 패스...


두번째 사용한 프로그램은 무료로 사용할 수 있는 Quantum GIS 이다.
Quantum GIS : http://www.qgis.org/
한글 언어를 지원하는 프로그램으로 별 어려움 없이 사용 할 수 있었다.

설치 후 프로그램을 실행시켜 shp를 읽어들이고자 할때는 아래 아이콘을 이용한다. 


벡터 레이어를 추가하여 데이터 셋을 읽어들이면 되는데 사용하고자 하는 shp 파일을 로드하면 된다.

이제 SVG로 변환을 하여야 하는데 기본적인 기능에서는 제공되지 않는다.

그래서 플러그인을 설치하여야 한다. 

메뉴에서 플러그인 -> Python 플러그인을 눌러 플러그인 설치 관리자를 실행 시키고 필터에 Simple SVG 로 검색한다.
하나 밖에 없으므로 눌러서 플러그인 설치를 하면 SVG로 변환할 준비 끝.

설치가 완료되면 플러그인 툴바가 프로그램 하단에 생성된다.
설치된 SVG 플러그인을 누르면 창이 뜨는데 창 가운데 Resize Map or Set Extent를 눌러서 크기를 조절해야한다.




위 이미지에서 처럼 Width와 Height의 화살표를 눌러 값을 바꾸고 우측의 Set을 누르면 지도 전체 크기가 변경된다.
그리고 꼭 !!  빨간색 상자로 표시된 버튼을 눌러 벡터 이미지도 지도 크기에 맞게 사이즈 조절을 해야만 한다.
(창을 닫지 않고도 눌러 지므로 창 닫지는 말자..)

빨간색 상자 버튼을 누르고 난 후 아래 Set Extent 의 Set 버튼을 눌러 표시된 지도의 X,Y를 설정하자.
(누르면 자동으로 맞춰진다.)

OK를 누르고 첫 창으로 돌아와 Browse를 눌러 저장하고자 할 경로와 파일명.svg 를 적어주고 OK를 누르면 변환이 완료된다.

이 변환된 파일을 에디트플러스나 다른 편집 프로그램으로 열어 아래 사이트에서 실제 지도로 변환되는지 확인해보자.

here > http://svgto.jvectormap.com/ 


아래는 변환된 결과. 


구멍 하나 없이 제대로 나온다. 

그런데!! 이 Quantum GIS를 이용하여 SVG로 변환할 경우 Shape가 가지고 있는 attribute를 같이 변환하지 않는다.
Simple SVG는 레이어 단위로 변환을 하기 때문에 id와 name이 따라가려면 레이어로 다 쪼개야하는데... 못하겟다;;

여튼 저 화면에서 Map name과 지역별 id, name을 설정하고 save를 누르면 자바 스크립트 파일로 다운로드가 가능하고
이를 jVectorMap에서 사용할수 있다. 


이제 어떤 파일이든지 Quantum GIS 만 있으면 jVectorMap에서 사용할 수 있다!!
그러나 이름은 손으로 다 입력해야한다. 


SVG Path만 있다면 jVectorMap으로 가능하다. 

아래는 SVG 샘플...  








위 샘플을 아래 사이트에서 확인할 수 있다.

svg to jvectormap : http://svgto.jvectormap.com

현재 작업하고 있는 프로젝트의 모든 프레임워크를 최신버전으로 세팅을 하고 서비스 클래스를 jUnit으로 작성해보았다...


Maven jUnit dependency
		
			junit
			junit
			4.7
			test
		


Maven Spring framework test
		
			org.springframework
			org.springframework.test
			3.2.3.RELEASE
		




AbstractApplicationContextTest.java
package com.openerp.service.test;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
		"file:src/resources/applicationContext-datasource.xml", 
		"file:src/resources/applicationContext-transaction.xml", 
		"file:src/resources/applicationContext.xml"
			})
public class AbstractApplicationContextTest {
	@Autowired ApplicationContext ctx;
}

여기서 ContextConfiguration의 locations이 문제가 많다.
일반적인 설정으로 dataSource, transaction, AOP 설정등 모든걸 하나의 xml에 설정을 한다면 하나만 쓰면 되지만, 위 처럼 각 기능별(또는 업무별)로 설정을 나누어 버리면 위 처럼 순서를 맞추어 주어야 한다.
그리고 applicationContext 파일의 위치가 조금 달라지면 classpath를 쓸때 생각을 많이 해야 한다.


ApplicationContext.xml
	
	
		
	

	
    
	  
	  
	  
	  
	  
			
	  
	
	
	
		 
	

어노테이션으로 bean을 자동으로 찾도록 했다.
jUnit 에서도 이 어노테이션을 가져올 수 있도록 지원하기 때문에 일일이 bean으로 서비스 클래스(테스트 대상)를 등록할 필요는 없다.

기타 설정은 패스...

UserServiceTest.java
package com.openerp.service.test;

import java.util.Calendar;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import com.openerp.common.utils.JSONUtil;
import com.openerp.common.utils.Parameters;
import com.openerp.domain.User;
import com.openerp.service.UserService;

public class UserServiceTest extends AbstractApplicationContextTest{
	private static Log log = LogFactory.getLog(UserServiceTest.class);
	
	@Resource(name="userService")
	private UserService userService;
	    
	@Test
	public void testSelectAllUser(){
		// 아래 Parameters는 그냥 Map으로 보시면 됨..
		Parameters params = new Parameters();
		params.addValue("isDisable", "");
		List users = userService.listUsers(params);
		// 아래 코드는 JSON 형식으로 바꿔주는 로직.. 
		System.out.println(JSONUtil.toJSON(users, null));
	}
}

어노테이션으로 등록된 UserService를 가지고 오기 위해 @Resource 어노테이션을 이용했다.
applicationContext.xml에 bean 태그를 이용해서 등록한 bean은 @Autowired가 가능하나, 어노테이션 검색으로 찾은 bean은 안되더라.
@Resource를 이용해서 검색하게 하니 정상적으로 작동을 한다...
지금 이 클래스는 UserService에 대한 테스트 인데 다른 Service에 대한 테스트도 해야 한다면 지금과 같이 AbstractApplicationContextTest 만 상속해서 사용을 하면 된다.
이는 각 서비스가 사용하는 설정(applicationContext)가 동일할 경우이고, 만약 각 업무별로 applicationContext을 나누어 사용한다면 AbstractApplicationContextTest 외에 다른 클래스를 만들어 상속해서 쓰면 된다.
(결론은 설정을 안쪼갰다면 하나의 슈퍼클래스에 설정을 밀어넣고 상속해서 사용한다는 것..)


jUnit 등 Test Case를 적용할 경우 편하긴 편하다.
서버(tomcat 등)를 재시작 할 필요도 없고, 코드만 고치고 해당 @Test 어노테이션이 붙은 메서드를 jUnit으로 실행만 하면 기존 방법(서버를 통한)과 동일한 결과를 이루어 낼 수 있다.
java, xml 코드 하나 고치고 빌드 -> 서버 재시작 -> 웹에서 액션 -> 결과 확인 무한 반복...
이제 이런걸 안하고도 서비스 클래스를 쉽게 작성할 수 있으니 개발 효율성이 향상되는 효과를 누릴 수 있다.

 

Security 3.1.4를 사용하면서 LoginUrl 설정을 하면서 아래와 같은 워닝을 보았다.. 
	
		
		
	

확인해 본 결과 아래와 같이 변경 되었다..

org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint.setLoginFormUrl(String) 
          use constructor injection 

그러므로 아래와 같이 변경해준다..
	
		
		
	


아래는 deprecated 된 항목을 살펴볼 수 있는 URL.

http://static.springsource.org/spring-security/site/docs/3.1.x/apidocs/deprecated-list.html 

 		Ext.Ajax.request({
	        url: '../com/ProxyJsonSimpleOneList.jsp',
	        contentType: 'json',
	        params: {
	        	name: 'value',
	        	today: new Date(),
	        	code: Ext.getCmp( 'brcCode' ).value
	        },
	        success: function(response){
	        	console.log(response);
	        },
	        failure: function(response, opts) {
	        	commonExtAjaxFailure(response, opts);
	        }
	    });





dddd

'Web > extjs4' 카테고리의 다른 글

Ext.create() and Ext.widget() 의 차이점...  (0) 2013.07.26
Ext.Ajax  (0) 2013.07.22
extjs grid 헤더 통합 및 하단 합계 추가.  (0) 2012.04.27
extjs grid dataStore onLoad 처리.  (0) 2012.04.24
extjs grid double click event  (0) 2012.04.23
extjs grid 헤더와 컬럼 따로 정렬하기  (0) 2012.04.23
java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;)V

이런 에러가 나는데... SLF4J와 Spring Context 가 가지고 있는 slf4j 가 충돌이 나서 그런거므로 maven 설정을 아래와 같이..

 
		
			org.springframework
			org.springframework.spring-library
	    	libd
			3.2.3.RELEASE
			
		        
					javax.servlet
		            com.springsource.javax.servlet
				
		        
		        	org.springframework.context
		        	org.springframework
		        
		        
		        	
		        		org.springframework.context.support
		        	
		        	org.springframework
		        
			
		

		
			org.springframework
			spring-context
			3.2.3.RELEASE
			
                
                
                    commons-logging
                    commons-logging
                 
            
		
		
		
			org.springframework
			spring-context-support
			3.2.3.RELEASE
			
                
                
                    commons-logging
                    commons-logging
                 
            
		

GenericMyBatisDaoSupport.java
package com.openerp.common.dao;

import java.io.Serializable;
import java.util.ArrayList;

import org.apache.ibatis.exceptions.PersistenceException;

public interface GenericMyBatisDaoSupport{
	public T get(PK id) throws PersistenceException;//get obj of type T by the primary key 'id' 
	public ArrayList getAll() throws PersistenceException;//get all objects of type T
	public int insert(T objInstance) throws PersistenceException;//insert an object of type T into the database
	int update(T transientObject) throws PersistenceException; //update an object of type T    
	int delete(PK id)  throws PersistenceException;//delete an object of type T
}




AbstractGenericMyBatisDao.java
package com.openerp.common.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class AbstractGenericMyBatisDao implements GenericMyBatisDaoSupport {
	
	private static Logger log = LoggerFactory.getLogger(AbstractGenericMyBatisDao.class);
	private static final String NAMESPACE = "Mapper"; 

	@Autowired
	private SqlSessionFactory sqlSessionFactory; //reference to mybatis session factory 
	private Class type;

	/** 
	 * Define prefixes for easier naming convetions between XML mapper files and the DAO class 
	 **/
	public static final String PREFIX_SELECT_QUERY = "get";     //prefix of select queries in mapper files (eg. getAddressType) 
	public static final String PREFIX_INSERT_QUERY = "insert"; //prefix of insert queries in mapper files (eg. insertAddressType)
	public static final String PREFIX_UPDATE_QUERY = "update";  //prefix of update queries in mapper files (eg. updateAddressType)
	public static final String PREFIX_DELETE_QUERY = "delete";  //prefix of delete queries in mapper files (eg. deleteAddressType)
	public static final String PREFIX_LIST_QUERY = "list";  //prefix of delete queries in mapper files (eg. deleteAddressType)

	/** Default Constructor */
	public AbstractGenericMyBatisDao(Class type) {
		this.type = type;
	}
	
	/** Default Constructor */
	public AbstractGenericMyBatisDao(Class type, SqlSessionFactory sf) {
		this.type = type;
		this.sqlSessionFactory = sf;
		if(sf==null)
			log.error("Error: Could not instantiate MyBatisDAO. Loading myBatis sessionFactory failed.");  
	}

	/** Use this method to get a session factory for using in any methods impelmented in child dao classes */
	protected SqlSessionFactory getSessionFactory() {
		return sqlSessionFactory;
	}

	/** 
	 *  Default get by id method. 
	 *  

* Almost all objects in the db will * need this (except mapping tables for multiple joins, which you * probably shouldn't even have as objects in your model, since proper * MyBatis mappings can take care of that). *

* Example: *
* If your DAO object is called CarInfo.java, * the corresponding mapper query id should be: <select id="getCarInfo" ... */ @SuppressWarnings("unchecked") public T get(PK id) throws PersistenceException { SqlSession session = sqlSessionFactory.openSession(); T obj = null; try { String query = this.type.getSimpleName()+NAMESPACE+"."+PREFIX_SELECT_QUERY+this.type.getSimpleName(); //If the object's calls name is AddressType.java, this matches the mapper query id: "namespace.getAddressType" obj = (T)session.selectOne(query,id); } finally { session.close(); } return obj; } /** * Method returns all rows for this object. *

* Example: *
* If your DAO object is called CarInfo.java, * the corresponding mapper query id should be: <select id="getAllCarInfo" ... *

* SQL Executed: select * from [tablename] *

* Notes: *
* Consider overdiding this method in order to handle large numbers of objects * with multiple references. * LAZY LOADING should be enabled in this case, otherwise you might run out of memory (eg. get all UserAccounts if the table has 1,000,000 rows) * look into the aggresiveLazyLoading property * */ @SuppressWarnings("unchecked") public ArrayList getAll() throws PersistenceException { SqlSession session = sqlSessionFactory.openSession(); ArrayList list = null; try { String query = this.type.getSimpleName()+NAMESPACE+"."+PREFIX_SELECT_QUERY+"All"+this.type.getSimpleName(); list = (ArrayList)session.selectList(query); } finally { session.close(); } return list; } /** * Method returns first object which matches the given name (exact match). *

* It's up to you to decide what constitutes an object's name. Typically you would have a * NAME column in the table, but not all objects have this. Generally this method should be overriden (if you need it at all) * in the child dao class. *

* Example: *
* If your DAO object is called CarInfo.java, * the corresponding mapper query id should be: <select id="getCarInfoByName" ... *

* SQL Executed (example): select * from [tablename] where NAME = ? * */ @SuppressWarnings("unchecked") public T getByName(String name) throws PersistenceException { SqlSession session = sqlSessionFactory.openSession(); T obj = null; try { String query = this.type.getSimpleName()+NAMESPACE+"."+PREFIX_SELECT_QUERY+this.type.getSimpleName()+"ByName"; obj = (T)session.selectOne(query, name); } finally { session.close(); } return obj; } /** * Method inserts the object into the table. *

* You will usually override this method, especially if you're inserting associated objects. *
* Example: *
* If your DAO object is called CarInfo.java, * the corresponding mapper query id should be: <insert id="createCarInfo" ... *

* SQL Executed (example): insert into [tablename] (fieldname1,fieldname2,...) values(value1,value2...) ... * */ public int insert(T o) throws PersistenceException{ SqlSession session = sqlSessionFactory.openSession(); Integer status = null; try { String query = this.type.getSimpleName()+NAMESPACE+"."+PREFIX_INSERT_QUERY+o.getClass().getSimpleName(); status = (Integer)session.insert(query, o); session.commit(); } finally { session.close(); } return status; } /** * Method updates the object by id. *

* You will usually override this method. But it can be used for simple objects. *
* Example: *
* If your DAO object is called CarInfo.java, * the corresponding mapper query id should be: <update id="updateCarInfo" ... *

* SQL Executed (example): update [tablename] set fieldname1 = value1 where id = #{id} * */ public int update(T o)throws PersistenceException { SqlSession session = sqlSessionFactory.openSession(); Integer status = null; try { String query = this.type.getSimpleName()+NAMESPACE+"."+PREFIX_UPDATE_QUERY+o.getClass().getSimpleName(); status = session.update(query, o); session.commit(); } finally { session.close(); } return status; } /** * Method deletes the object by id. *

* Example: *
* If your DAO object is called CarInfo.java, * the corresponding mapper query id should be: <delete id="deleteCarInfo" ... *

* SQL Executed (example): update [tablename] set fieldname1 = value1 where id = #{id} * */ public int delete(PK id) throws PersistenceException{ SqlSession session = sqlSessionFactory.openSession(); Integer status = null; try { String query = this.type.getSimpleName()+NAMESPACE+"."+PREFIX_DELETE_QUERY+this.type.getSimpleName(); status = session.delete(query, id); session.commit(); } finally { session.close(); } return status; } }


RoleService.java
package com.openerp.service;

import com.openerp.domain.Role;

public interface RoleService {
	Role getRole(int key);
}


RoleServiceImpl.java
package com.openerp.service.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.openerp.dao.RoleDao;
import com.openerp.domain.Role;
import com.openerp.service.RoleService;

@Service("roleMgr")
public class RoleServiceImpl implements RoleService{
	
	Log logger = LogFactory.getLog(this.getClass());
	
	@Autowired
	private RoleDao dao;

	@Override
	public Role getRole(int key) {
		return dao.get(key);
	}
	
}


Controller
package com.openerp.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.arnx.jsonic.JSONException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.openerp.common.utils.JSONUtil;
import com.openerp.service.RoleService;

@Controller
public class JsonController {

	@Autowired private RoleService roleMgr;
	
	@RequestMapping("/json/sampleData.do")
	public void sendJsonData(HttpServletRequest req, HttpServletResponse rep){
		int key = Integer.parseInt(req.getParameter("key"));
		try {
			rep.setCharacterEncoding("UTF-8");
			rep.getWriter().write(JSONUtil.toJSON(roleMgr.getRole(key), null));
			
		} catch (JSONException e) {
			e.printStackTrace();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


SqlMapConfig.xml



	
		 
	

	
		
	

	



mapUnderscoreToCamelCase 이 속성을 안적어주면 아래 필드가 매핑되지 않는다.
ROLE_NAME_KOR 이런 필드는 카멜 표기법으로 표기하지 않기 때문에 꼭 위의 속성이 필요하다...


SQL File :

Full Source :
설명 적는게 너무 귀찮으다...

+ Recent posts