form parameter name == vo 변수이름 == DB column 이름
동일한 이름으로 설정하면 유지보수가 용이하다
단위테스트를 도와주는 junit 라이브러리.
단위테스트?
개별젹인 소스코드의 단위(모듈 전체 혹은 하나의 함수)를 관련된 데이터나 절차에 따라 테스트함
논리적 오류 조기발견. 리팩토링하거나 업그레이드 후 상태테스트 가능
pom.xml
에 기본으로 들어가 있음. <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
프로젝트 오른쪽클릭 -> build path -> add libraries -> junit 4
로 버전 바꿔주기
src/test/java(resources)
는 서버가 돌아가지 않아도 사용할 수 있는 테스트용 패키지다.
테스트용 클래스에 어노테이션 추가하기!!(안쓰면 안됨. 겪음^^;)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
@WebAppConfiguration
private static final Logger LOGGER=LoggerFactory.getLogger(OracleJDBCTest.class);
@test
를 넣으면 알아서 단위테스트용 메소드로 인식함. 서버가 없어도 ctrl+f11누르면 실행됨
@Test
public void testOracleConnect() {
Connection conn=null;
try {
DriverManager.registerDriver(new OracleDriver());
conn=DriverManager.getConnection(URL, USER, PASSWORD);
LOGGER.info("oracle 연결 성공");
} catch (SQLException e) {
LOGGER.error("oracle 연결 실패 : "+e.getMessage());
} finally {
try {
conn.close();
LOGGER.info("oracle 연결 해제 성공");
} catch (SQLException e) {
LOGGER.error("oracle 연결 해제 실패 : "+e.getMessage());
}
}
}
에러가 발생하지 않으면 이런식으로 jUnit 상태창이 뜬다
Spring Framework가 관리하는 DataSource 객체를 빌려쓴다
root-context.xml에서 bean으로 선택된 DataSource객체 주입하는 것.
javax.sql.DataSource
@Autowired
private DataSource ds;
@Test
public void testDataSource() {
Connection conn=null;
try {
conn=ds.getConnection();
LOGGER.info("DataSource 연결 성공");
} catch (SQLException e) {
LOGGER.error("DataSource 연결 실패 : "+e.getMessage());
} finally {
try {
conn.close();
LOGGER.info("DataSource 연결 반환 성공");
} catch (SQLException e) {
LOGGER.error("DataSource 연결 반환 실패 : "+e.getMessage());
}
}
}
@Autowired
private SqlSessionFactory sessionFactory;
@Test
public void testSqlSessionFactory() {
SqlSession session = sessionFactory.openSession();
if (session != null) {
LOGGER.info("SqlSession 생성 성공");
} else {
LOGGER.info("SqlSession 생성 실패");
}
}
sqlSession은 기존 자바 DAOImple에서 사용하던 db쿼리 메소드(insert, select, update, delete 같은)를 축약해서 함수로 가지고있음.
mapper/board-mapper.xml
에서 <insert>
태그 생성<insert id="insert">
insert into ${test_board} (${title}, ${content}, ${userid})
values(#{title}, #{content}, #{userid})
</insert>
mapper/board-mapper.xml
에 있는 namespace와 동일한 값 사용함private static final String NAMESPACE="edu.spring.ex02.BoardMapper";
@Autowired
private SqlSession sqlSession;
@Test
public void testInsert() {
BoardVO vo=new BoardVO(0, "hello", "hello", "dodo", null);
int result=sqlSession.insert(NAMESPACE+".insert", vo);
//insert(key, value)
LOGGER.info(result+"행 삽입");
}
root-context.xml
에 bean으로 등록해야함<context:component-scan... />
private static final String NAMESPACE="edu.spring.ex02.BoardMapper";
@Autowired
private SqlSession sqlSession;
@Override
public int insert(BoardVO vo) {
LOGGER.info("insert() 호출");
return sqlSession.insert(NAMESPACE+".insert", vo);
}
board-mapper.xml
의 select태그 리턴타입에 들어갈 클래스 경로를 설정한다. 모델형태로 쓸 경로를 알아냄.
<typeAliases>
<package name="edu.spring.ex02.domain"/>
</typeAliases>
PageCriteria
를 매개변수로 매핑에 넘겨준다@Override
public List<BoardVO> select(PageCriteria c) {
LOGGER.info("select() 호출 : PageCriteria = "+c);
return sqlSession.selectList(NAMESPACE+".paging", c);
}
<select id="paging" resultType="BoardVO">
select b.${bno}, b.${title}, b.${content}, b.${userid}, b.${cdate}
from (
select rownum rn, a.*
from(
select * from ${test_board} order by ${bno} desc
)a
)b
where rn between #{start} and #{end}
</select>
#{start}
, #{end}
로 페이지숫자를 입력하면 알아서 getter 메소드명으로 찾아가는 것, VO를 넘겨줄때도 똑같다.
내부적으로 쿼리가 읽히면 c.getStart()
, c.getEnd()
를 PageCriteria클래스에서 가져오게된다.
private void testSelectPagescope() {
PageCriteria c=new PageCriteria(1, 3);
List<BoardVO> list=dao.select(c);
for(BoardVO vo:list) {
LOGGER.info(vo.toString());
}
}
현재 전체데이터가 5개라면 (1,3) 입력 시 5,4,3 테이블번호의 정보가 출력되고 (2,3) 입력 시 2,1 테이블번호의 vo가 출력되면 테스트 성공적