전자정부 표준 프레임워크 네 번째는 포스트부터는 실행환경 관련이다.

데이터처리랑, 배치처리랑, 화면처리랑 많다아.......

 

먼저 데이터처리는 아래와 같은 3 Tier Architecture를 따라서 동작한다.

자바 코드를 작성하기 전에 구동 환경 먼저 설정해 주어야 한다. 
dataSource 설정은 context-datasource.xml에 빈 설정 추가하기.

	<bean id="dataSource" 
    	class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${db.driver}" />
		<property name="url" value="${db.dburl}" />
		<property name="username" value="${db.username}" />
		<property name="password" value="${db.password}" />
		<property name="defaultAutoCommit" value="false" />
		<property name="poolPreparedStatements" value="true" />
	</bean>



<!-- [Step 1-2] DataSource 설정 -->
	<jdbc:embedded-database id="dataSource" type="HSQL">
		<jdbc:script location="META-INF/testdata/sample_schema_hsql.sql" />
	</jdbc:embedded-database>

transaction 설정으로는 context-transaction.xml 파일에다가 해 주면 되는데,
트랜잭션 annotation을 이용하면 대상 메소드에 개별적으로 트랜잭션을 지정할 수 있다는 장점이 있으나,
보통 AOP 형식(tx:aop)으로 선언하여 트랜잭션 대상 메서드들에 일괄 지정하는 경우가 많다고 한다.

<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<tx:annotation-driven transaction-manager="txManager" />

이번에는 mybatis 연동을 위한 설정인데 이거는 context-mybatis.xml 파일에다가 해 주면 된다.

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
	    <property name="dataSource" ref="dataSource" />
	    <property name="configLocation" value="classpath:/META-INF/sqlmap/sql-mybatis-config.xml" />
</bean>

mybatis 연동을 위한 설정을 해줬다면 config 설정 파일도 필요한 부분 작성해주기.
나머지 다른 context로 시작하는 파일들은 확인만 한번 해 주면 구동 환경 설정은 끝이라고 강의에선 그랬다.

이제 자바 클래스들을 작성해주면 되는데,
ServiceImpl이랑 DAO랑 SQL 매핑파일이랑 그거...자바로 게시판 한번 구현해봤다면 다 작성해봤을 파일들 작성해주기.

강의에서는 확인을 주로 아래처럼 테스트코드 파일 만들어서 성공/실패를 확인한다.

package egovframework.lab.dataaccess.service;

import static org.junit.Assert.*;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.jdbc.JdbcTestUtils;
import org.springframework.transaction.annotation.Transactional;

import egovframework.rte.fdl.cmmn.exception.EgovBizException;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:META-INF/spring/context-*" })
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = false)
@Transactional
public class EmpServiceTest {

	// TODO [Step 4-1] EmpServiceTest 실행

	@Resource(name = "dataSource")
	DataSource dataSource;

	@Resource(name = "empService")
	EmpService empService;

	@Before
	public void onSetUp() throws Exception {
		// 편의상 각 테스트 메서드 수행 전에
		// 외부의 스크립트 파일(sample_schema_hsql.sql)로 DB를 초기화하도록 설정
		JdbcTestUtils.executeSqlScript(new JdbcTemplate(dataSource),
				new ClassPathResource("META-INF/testdata/sample_schema_hsql.sql"), true);
	}

	/**
	 * 사원정보 생성
	 * 
	 * @throws ParseException
	 */
	public EmpVO makeVO() throws ParseException {
		EmpVO vo = new EmpVO();

		// empNo는 Biz. 서비스 내에서 IDGeneration Service 에 의해 key를 생성하고 설정
		vo.setEmpName("홍길동");
		vo.setJob("개발자");
		vo.setMgr(new BigDecimal(7903));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", java.util.Locale.getDefault());
		vo.setHireDate(sdf.parse("2009-07-10"));
		vo.setSal(new BigDecimal(2000));
		vo.setComm(new BigDecimal(0));
		vo.setDeptNo(new BigDecimal(20));

		return vo;
	}

	public void checkResult(EmpVO vo, EmpVO resultVO) {
		assertNotNull(resultVO);
		assertEquals(vo.getEmpNo(), resultVO.getEmpNo());
		assertEquals(vo.getEmpName(), resultVO.getEmpName());
		assertEquals(vo.getJob(), resultVO.getJob());
		assertEquals(vo.getMgr(), resultVO.getMgr());
		assertEquals(vo.getHireDate(), resultVO.getHireDate());
		assertEquals(vo.getSal(), resultVO.getSal());
		assertEquals(vo.getComm(), resultVO.getComm());
		assertEquals(vo.getDeptNo(), resultVO.getDeptNo());
	}

	/** 사원정보 입력 */
	@Test
	public void testInsertEmp() throws Exception {
		EmpVO vo = makeVO();

		// insert
		BigDecimal empNo = empService.insertEmp(vo);
		vo.setEmpNo(empNo);

		// select
		EmpVO resultVO = empService.selectEmp(vo);

		// check
		checkResult(vo, resultVO);
	}

	/** 사원정보 수정 */
	@Test
	public void testUpdateEmp() throws Exception {
		EmpVO vo = makeVO();

		// insert
		BigDecimal empNo = empService.insertEmp(vo);
		vo.setEmpNo(empNo);

		// data change
		vo.setEmpName("홍길순");
		vo.setJob("설계자");

		// update
		empService.updateEmp(vo);

		// select
		EmpVO resultVO = empService.selectEmp(vo);

		// check
		checkResult(vo, resultVO);
	}

	/** 사원정보 삭제 */
	@Test
	public void testDeleteEmp() throws Exception {
		EmpVO vo = makeVO();

		// insert
		BigDecimal empNo = empService.insertEmp(vo);
		vo.setEmpNo(empNo);

		// delete
		empService.deleteEmp(vo);

		// select
		try {
			@SuppressWarnings("unused")
			EmpVO resultVO = empService.selectEmp(vo);
			fail("EgovBizException 이 발생해야 합니다.");
		} catch (Exception e) {
			assertNotNull(e);
			assertTrue(e instanceof EgovBizException);
			assertEquals("info.nodata.msg", ((EgovBizException) e).getMessageKey());
			assertEquals("해당 데이터가 없습니다.", e.getMessage());
		}
	}

	/** 사원정보 목록조회 */
	@Test
	public void testSelectEmpList() throws Exception {
		EmpVO vo = makeVO();

		// insert
		BigDecimal empNo = empService.insertEmp(vo);
		vo.setEmpNo(empNo);

		// 검색조건으로 empNo 설정
		EmpVO searchVO = new EmpVO();
		searchVO.setEmpNo(vo.getEmpNo());

		// selectList
		List<EmpVO> resultList = empService.selectEmpList(searchVO);

		// empNo 조건에 대한 결과는 1건일 것임
		assertNotNull(resultList);
		assertTrue(resultList.size() > 0);
		assertEquals(1, resultList.size());
		checkResult(vo, resultList.get(0));

		// 검색조건으로 empName 설정 - '%' || #{empName} || '%'
		EmpVO searchVO2 = new EmpVO();
		searchVO2.setEmpName(""); // '%' || '' || '%' // --> '%%'

		// selectList
		List<EmpVO> resultList2 = empService.selectEmpList(searchVO2);

		// like 조건에 대한 결과는 1건 이상일 것임
		assertNotNull(resultList2);
		assertTrue(resultList2.size() > 0);
	}

}

JUnit 단위테스트 책 앞에만 살짝 봤었었는데 이거도 북리뷰 해야하는데 아무튼 그래서인지,
테스트 코드 라인별로 따라가고 테스트 해보는게 익숙하지는 않지만 이해는 완료하고 데이터처리는 여기서 끝.

'Backend' 카테고리의 다른 글

전자정부표준프레임워크_06  (0) 2022.03.11
전자정부표준프레임워크_05  (0) 2022.03.11
전자정부표준프레임워크_03  (0) 2022.03.10
전자정부표준프레임워크_02  (0) 2022.03.07
전자정부표준프레임워크_01  (0) 2022.02.26