본문 바로가기
프레임워크

[전자정부 표준프레임워크] 표준프레임워크 4.0 (베타) DB 연동 시작하기

by Master 신 2022. 2. 12.

표준프레임워크 4.0 (베타) DB 연동을 해보자.

연동을 해볼 DB는 Oracle, MS SQL, My SQL 3가지만 진행 해보자.

표준프레임워크 4.0은 기본적으로 hsql 로 셋팅되어 있다.

hsql 이란?

HSQLDB(Hyper SQL Database, 하이퍼 SQL 데이터베이스)는 자바로 작성된 관계형 데이터베이스 관리 시스템이다. JDBC 드라이버를 갖추고 있으며 SQL-92, SQL:2008, SQL:2011 표준의 상당 부분을 지원한다.[2] 고속의[3] 소형 (버전 2.2 기준으로 약 1300 킬로바이트) 데이터베이스 엔진을 제공하며 인메모리와 디스크 기반 테이블을 둘 다 제공한다. 임베디드 및 서버 모드 둘 다 이용 가능하다.
게다가 초소형 웹 서버, 명령 줄, GUI 관리 도구(애플릿으로 실행 가능) 등의 도구들과 수많은 데모 예제를 포함하고 있다. Kaffe와 같은 자바 구현체를 포함하여 버전 1.1 이상의 자바 런타임에서 실행할 수 있다.
HSQLDB는 BSD 허가서로 배포된다. 수많은 오픈 소스 소프트웨어 프로젝트의 데이터베이스 및 영구적인 엔진으로 이용되며, 이를테면 오픈오피스 베이스, 리브레오피스 베이스, 스탠드얼론 롤러 데모,[4] Jitsi VoIP, 그리고 버전 2.6 이상의 화상회의 클라이언트를 들 수 있다.[5] 매스매티카와 인스톨애니웨어(버전 8.0부터)와 같은 상용 제품에도 사용된다.
-위키백과

본격적으로 DB연동을 하기 전에 표준프레임워크 4.0 구조와 DB 연동 파일을 간단하게 살펴 보자.

src/main/java

 

java 파일중 살펴 볼 파일은 egovframework.com.config 패키지내에 있는 EgovConfigAppDatasource.java 파일이다.

package egovframework.com.config;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;

/**
 * @ClassName : EgovConfigAppDatasource.java
 * @Description : DataSource 설정
 *
 * @author : 윤주호
 * @since  : 2021. 7. 20
 * @version : 1.0
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일              수정자               수정내용
 *  -------------  ------------   ---------------------
 *   2021. 7. 20    윤주호               최초 생성
 * </pre>
 *
 */
@Configuration
@PropertySources({
	@PropertySource("classpath:/egovframework/egovProps/globals.properties")
}) //CAUTION: min JDK 8
public class EgovConfigAppDatasource {

	//	@Value("${Globals.DbType}")
	//	private String dbType;
	//
	//	@Value("${Globals.DriverClassName}")
	//	private String className;
	//
	//	@Value("${Globals.Url}")
	//	private String url;
	//
	//	@Value("${Globals.UserName}")
	//	private String userName;
	//
	//	@Value("${Globals.Password}")
	//	private String password;

	@Autowired
	Environment env;

	private String dbType;

	private String className;

	private String url;

	private String userName;

	private String password;

	@PostConstruct
	void init() {
		dbType = env.getProperty("Globals.DbType");
		//Exception 처리 필요
		className = env.getProperty("Globals." + dbType + ".DriverClassName");
		url = env.getProperty("Globals." + dbType + ".Url");
		userName = env.getProperty("Globals." + dbType + ".UserName");
		password = env.getProperty("Globals." + dbType + ".Password");
	}

	/**
	 * @return [dataSource 설정] HSQL 설정
	 */
	private DataSource dataSourceHSQL() {
		return new EmbeddedDatabaseBuilder()
			.setType(EmbeddedDatabaseType.HSQL)
			.setScriptEncoding("UTF8")
			.addScript("classpath:/db/shtdb.sql")
			//			.addScript("classpath:/otherpath/other.sql")
			.build();
	}

	/**
	 * @return [dataSource 설정] basicDataSource 설정
	 */
	private DataSource basicDataSource() {
		BasicDataSource basicDataSource = new BasicDataSource();
		basicDataSource.setDriverClassName(className);
		basicDataSource.setUrl(url);
		basicDataSource.setUsername(userName);
		basicDataSource.setPassword(password);
		return basicDataSource;
	}

	/**
	 * @return [DataSource 설정]
	 */
	@Bean(name = {"dataSource", "egov.dataSource", "egovDataSource"})
	public DataSource dataSource() {
		if ("hsql".equals(dbType)) {
			return dataSourceHSQL();
		} else {
			return basicDataSource();
		}
	}
}

마지막 부분을 우선 보자. 만약 hsql 일 경우 dataSourceHSQL 을 아닐 경우 basicDataSource 을 리턴하고 있다.

hsql 일경우는 shtdb.sql 스크립트를 실행 시키고,

다른 dbType 일 경우는 해당 dbType 에 맞게 해당 db 쿼리가 있는 ooo.xml 을 시킨다.

그럼 이제 shtdb.sql 과 dbType 이 정의 되어 있는 globals.properties를 살펴 보자.

src/main/resources

 

우선 shtdb.sql 을 열어보자.

CREATE MEMORY TABLE LETTCCMMNCLCODE(CL_CODE CHAR(3) NOT NULL PRIMARY KEY,CL_CODE_NM VARCHAR(60),CL_CODE_DC VARCHAR(200),USE_AT CHAR(1),FRST_REGIST_PNTTM TIMESTAMP,FRST_REGISTER_ID VARCHAR(20),LAST_UPDT_PNTTM TIMESTAMP,LAST_UPDUSR_ID VARCHAR(20))
CREATE MEMORY TABLE LETTCCMMNCODE(CODE_ID VARCHAR(6) NOT NULL PRIMARY KEY,CODE_ID_NM VARCHAR(60),CODE_ID_DC VARCHAR(200),USE_AT CHAR(1),CL_CODE CHAR(3),FRST_REGIST_PNTTM TIMESTAMP,FRST_REGISTER_ID VARCHAR(20),LAST_UPDT_PNTTM TIMESTAMP,LAST_UPDUSR_ID VARCHAR(20),CONSTRAINT SYS_FK_86 FOREIGN KEY(CL_CODE) REFERENCES LETTCCMMNCLCODE(CL_CODE))
CREATE MEMORY TABLE LETTCCMMNDETAILCODE(CODE_ID VARCHAR(6) NOT NULL,CODE VARCHAR(15) NOT NULL,CODE_NM VARCHAR(60),CODE_DC VARCHAR(200),USE_AT CHAR(1),FRST_REGIST_PNTTM TIMESTAMP,FRST_REGISTER_ID VARCHAR(20),LAST_UPDT_PNTTM TIMESTAMP,LAST_UPDUSR_ID VARCHAR(20),PRIMARY KEY(CODE_ID,CODE),CONSTRAINT SYS_FK_89 FOREIGN KEY(CODE_ID) REFERENCES LETTCCMMNCODE(CODE_ID))
CREATE MEMORY TABLE LETTHEMPLYRINFOCHANGEDTLS(EMPLYR_ID VARCHAR(20) NOT NULL,CHANGE_DE CHAR(20) NOT NULL,ORGNZT_ID CHAR(20),GROUP_ID CHAR(20),EMPL_NO VARCHAR(20) NOT NULL,SEXDSTN_CODE CHAR(1),BRTHDY CHAR(20),FXNUM VARCHAR(20),HOUSE_ADRES VARCHAR(100) NOT NULL,HOUSE_END_TELNO VARCHAR(4),AREA_NO VARCHAR(4),DETAIL_ADRES VARCHAR(100) NOT NULL,ZIP VARCHAR(6) NOT NULL,OFFM_TELNO VARCHAR(20),MBTLNUM VARCHAR(20) NOT NULL,EMAIL_ADRES VARCHAR(50),HOUSE_MIDDLE_TELNO VARCHAR(4),PSTINST_CODE CHAR(8),EMPLYR_STTUS_CODE VARCHAR(15) NOT NULL,ESNTL_ID CHAR(20),PRIMARY KEY(EMPLYR_ID,CHANGE_DE))
......
INSERT INTO LETTCCMMNCLCODE VALUES('LET','전자정부 프레임워크 경량환경 템플릿','전자정부 프레임워크 경량환경 템플릿','Y','2011-08-31 00:00:00.000000000','SYSTEM','2011-08-31 00:00:00.000000000','SYSTEM')
INSERT INTO LETTCCMMNCODE VALUES('COM001','등록구분','게시판, 커뮤니티, 동호회 등록구분코드','Y','LET','2011-08-31 00:00:00.000000000','SYSTEM','2011-08-31 00:00:00.000000000','SYSTEM')
INSERT INTO LETTCCMMNCODE VALUES('COM003','업무구분','업무구분코드','Y','LET','2011-08-31 00:00:00.000000000','SYSTEM','2011-08-31 00:00:00.000000000','SYSTEM')
INSERT INTO LETTCCMMNCODE VALUES('COM004','게시판유형','게시판유형구분코드','Y','LET','2011-08-31 00:00:00.000000000','SYSTEM','2011-08-31 00:00:00.000000000','SYSTEM')

MEMORY TABLE을 생성하고 데이터를 INSERT 한다.

서버를 재기동 할 때마다 데이터가 초기화 되는 이유가 여기에 있다.

이제 globals.properties 파일을 열어 보자.

#-----------------------------------------------------------------------
#
#   globals.properties : 시스템 
#   
#-----------------------------------------------------------------------
#   1.  key = value 구조입니다.
#   2.  key값은 공백문자를 포함불가, value값은 공백문자를 가능
#   3.  key값으로 한글을 사용불가,   value값은 한글사용이 가능
#   4.  줄을 바꿀 필요가 있으면 '\'를 라인의 끝에 추가(만약  '\'문자를 사용해야 하는 경우는 '\\'를 사용)
#   5.  Windows에서의 디렉토리 표시 : '\\' or '/'  ('\' 사용하면 안됨)
#   6.  Unix에서의 디렉토리 표시 : '/'
#   7.  주석문 처리는  #사용
#   8.  value값 뒤에 스페이스가 존재하는 경우 서블릿에서 참조할때는 에러발생할 수 있으므로 trim()하거나 마지막 공백없이 properties 값을 설정할것
#-----------------------------------------------------------------------

# 운영서버 타입(WINDOWS, UNIX)
Globals.OsType = WINDOWS

# G4C 연결용 IP (localhost)
Globals.LocalIp = 127.0.0.1

# DB서버 타입(hsql,mysql,oracle,altibase,tibero) - datasource 및 sqlMap 파일 지정에 사용됨
Globals.DbType = hsql

# DB 접근 정보


#hsql - local hssql 사용시에 적용 (내장 hsql은 정보 필요 없음)
Globals.hsql.DriverClassName=net.sf.log4jdbc.DriverSpy
Globals.hsql.Url=jdbc:log4jdbc:hsqldb:hsql://127.0.0.1/sampledb
Globals.hsql.UserName=sa
Globals.hsql.Password=

# mysql
Globals.mysql.DriverClassName=net.sf.log4jdbc.DriverSpy
Globals.mysql.Url=jdbc:log4jdbc:mysql://127.0.0.1:3306/sht
Globals.mysql.UserName=root
Globals.mysql.Password=

#oracle
Globals.oracle.DriverClassName=oracle.jdbc.driver.OracleDriver
Globals.oracle.Url=jdbc:oracle:thin:@127.0.0.1:1521:egovfrm
Globals.oracle.UserName=
Globals.oracle.Password=


#altibase
Globals.altibase.DriverClassName=Altibase.jdbc.driver.AltibaseDriver
Globals.altibase.Url=jdbc:Altibase://127.0.0.1:1721/egovfrm?encoding=UTF-8
Globals.altibase.UserName=
Globals.altibase.Password=

#tibero
Globals.tibero.DriverClassName=com.tmax.tibero.jdbc.TbDriver
Globals.tibero.Url=jdbc:tibero:thin:@127.0.0.1:1821:egovfrm
Globals.tibero.UserName=
Globals.tibero.Password=

#cubrid
Globals.cubrid.DriverClassName=cubrid.jdbc.driver.CUBRIDDriver
Globals.cubrid.Url=jdbc:cubrid:127.0.0.1:33000:sht:::?charset=utf-8
Globals.cubrid.UserName=
Globals.cubrid.Password=

# MainPage Setting
Globals.MainPage = /cmm/main/mainPage.do

여러가지의 dbType 들에 대한 정의가 있으며, 사용할 db 정보를 넣어주고 Globals.DbType 의 값만 변경 해주면 된다.

기본 셋팅은 [Globals.DbType = hsql] 이고, 만약 Oracle DB를 연동하고 싶다면 Globals.DbType = oracle 로 변경하고,

아래와 같이 DB 정보를 입력해 주면 된다.

#oracle
Globals.oracle.DriverClassName=oracle.jdbc.driver.OracleDriver
Globals.oracle.Url=jdbc:oracle:thin:@127.0.0.1:1521:egovfrm
Globals.oracle.UserName=mastershin
Globals.oracle.Password=1234

 

이제 mapper 폴더를 한번 살펴 보자.

mapper.xml 파일들

동일한 업무 mapper.xml 파일들이 각 DbType 별로 준비 되어 있다.

다시 설명하자면 globals.properties 파일에서 Globals.DbType 을 설정한 것에 따라서 분기되어 처리 되는 것이다.

hsql을 메모리 DB를 사용하는 방식이고, 나머지 DB 들은 (업무이름)_SQL_(Globals.DbType 설정값).xml 파일을 사용하는 방식이다.

java 파일중 egovframework.com.config 패키지내에 있는 EgovConfigAppMapper.java 파일을 열어보자.

package egovframework.com.config;

import java.io.IOException;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.support.lob.DefaultLobHandler;

/**
 * @ClassName : EgovConfigAppMapper.java
 * @Description : Mapper 설정
 *
 * @author : 윤주호
 * @since  : 2021. 7. 20
 * @version : 1.0
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일              수정자               수정내용
 *  -------------  ------------   ---------------------
 *   2021. 7. 20    윤주호               최초 생성
 * </pre>
 *
 */
@Configuration
@PropertySources({
	@PropertySource("classpath:/egovframework/egovProps/globals.properties")
})
public class EgovConfigAppMapper {
	@Autowired
	DataSource dataSource;

	@Autowired
	Environment env;

	private String dbType;

	@PostConstruct
	void init() {
		dbType = env.getProperty("Globals.DbType");
	}

	@Bean
	@Lazy
	public DefaultLobHandler lobHandler() {
		return new DefaultLobHandler();
	}

	@Bean(name = {"sqlSession", "egov.sqlSession"})
	public SqlSessionFactoryBean sqlSession() {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);

		PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();

		sqlSessionFactoryBean.setConfigLocation(
			pathMatchingResourcePatternResolver
				.getResource("classpath:/egovframework/mapper/config/mapper-config.xml"));

		try {
			sqlSessionFactoryBean.setMapperLocations(
				pathMatchingResourcePatternResolver
					.getResources("classpath:/egovframework/mapper/let/**/*_" + dbType + ".xml"));
		} catch (IOException e) {
			// TODO Exception 처리 필요
		}

		return sqlSessionFactoryBean;
	}

	@Bean
	public SqlSessionTemplate egovSqlSessionTemplate(@Qualifier("sqlSession") SqlSessionFactory sqlSession) {
		SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSession);
		return sqlSessionTemplate;
	}
}

지금 까지 표준프레임워크 4.0 (베타) DB 연동을 하기 위하여 기본적인 구조와 관련 파일들을 살펴 봤다.