Spring framework 예제
목차
Spring Framework의 기본적인 환경을 잡았다면 본격적인 설계 – 구현 시작

첫 번째 기능은 로그인 기능이다. 회원 정보에 필요한 사항은 다음과 같다.
Column Name | DataType | Option |
ID | varchar2(20) | Primary Key |
PW | varchar2(30) | Not null |
Name | varchar2(10) | Not null |
HP | varchar2(20) | Not null |
varchar2(50) | ||
Regist | DATE | Default SYSDATE |
create table member ( id varchar2(20) not null, pw varchar2(30) not null, name varchar2(10) not null, hp varchar2(20) not null, email varchar2(50), regist date default sysdate, constraint member_pk primary key(id))
DB설계 후 MVC 패턴으로 개발 시 첫 번째로 해야할 일은 VO(Value Object)작성이다. DTO(Data Transfer Object)와 같은 뜻으로 데이터를 담는 객체가 되겠다.
글쓴이는 패키지를 크게 3가지로 나누었다. Controller(+Action Mapping), DAO, DTO 이다. 이 세 개의 패키지 안에는 오로지 POJO가 들어가고 Controller에서 요청에 대한 처리를 한 후 ViewResolver로 JSP(View)로 값을 전달한 후 Forward시킬 것이다.

Member.java 에는 데이터를 담을 수 있도록 멤버변수와 Getter, Setter로 구성되어 있다. 자세한 코드는 아래와 같다.
package com.board.dto; import org.springframework.stereotype.Repository; @Repository public class Member { private String id; private String pw; private String name; private String hp; private String email; private String regist; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPw() { return pw; } public void setPw(String pw) { this.pw = pw; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getHp() { return hp; } public void setHp(String hp) { this.hp = hp; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getRegist() { return regist; } public void setRegist(String regist) { this.regist = regist; } }
DTO를 만들었다면 만든 DTO를 갖고 할 행위(Function)을 정의해준다. 바로 DAO(Data Access Object)가 되겠다. 회원과 관련된 Action은 가입(Insert), 수정(Update), 탈퇴(Delete), 마지막으로 세션에 값을 넣기 위해 회원의 정보를 갖고오는 것(SelectOne)이다.
DAO에서는 이름 그대로 데이터베이스에 접근을 하기 때문에 SQL문을 작성해야 한다. 먼저 앞 포스팅에서 설정했던 MyBATIS의 member-mapper.xml을 작성하도록 한다.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="Member"> <insert id="add" parameterType="com.board.dto.Member"> INSERT INTO member VALUES (#{id}, #{pw}, #{name}, #{hp}, #{email}, DEFAULT) </insert> <update id="mod" parameterType="com.board.dto.Member"> UPDATE member SET pw=#{pw}, email=#{email}, hp=#{hp} WHERE id=#{id} </update> <delete id="del" parameterType="string"> DELETE FROM member WHERE id=#{id} </delete> <select id="get" parameterType="string" resultType="com.board.dto.Member"> SELECT id, pw, name, hp, email, regist FROM member WHERE id=#{id} </select> </mapper>
SQL 작성이 끝났다면 DAO를 작성한다. MyBATIS를 사용하기 전이라면 Connection부터 Statement, ResultSet … 열고 닫기까지 모든 일을 프로그래머가 해야 했을 것이다. 아래 더욱 간단해진 DAO를 볼 수 있을 것이다.
package com.board.dao; import javax.inject.Inject; import org.apache.ibatis.session.SqlSession; import org.springframework.stereotype.Repository; import com.board.dto.Member; @Repository public class MemberDAO { @Inject private SqlSession sql; public void insert(Member member) { sql.insert("Member.add", member); } public void update(Member member) { sql.update("Member.mod", member); } public void delete(String id) { sql.delete("Member.del", id); } public Member select(String id) { return sql.selectOne("Member.get", id); } }
@Inject : Spring Framework에서 의존성을 주입하는 Annotation이다. SqlSession은 잘 보면 인터페이스이며 어디선가 Implements해서 구현했을 것이다.

예상했겠지만 root-context.xml에 bean으로 등록해두었던 “SqlSessionTemplate”이 주입되어 사용되고 있는 것이다.
MyBATIS mapper.xml 파일에 있는 SQL문과 맵핑시키려면 해당하는 Method를 사용해야 하는데 너무 직관적이여서 설명할 필요가 없는 부분이다. 그냥 SqlSession 객체 만들고, 그 객체의 insert, update, delete, selectone … 를 사용하면 된다.
매개변수도 너무 직관적이다. mapper.xml 에 mapper태그 안에 있는 namespace가 최상위가 되며 그 후로 ‘.’ 점을 찍어 맵핑(자바처럼)하면 된다.
마지막으로 Spring Framework가 지금까지 만든 POJO를(DTO, DAO)를 찾아서 @Repository(bean으로 등록하는 Annotation)를 할 수 있게끔 해준다.
src > main > webapp > WEB-INF > spring > appServlet > servlet-context.xml을 열어서 component-scan을 다음과 같이 수정한다.
<context:component-scan base-package="com.board.*" />
이렇게 되면 Spring Framework가 해당 POJO를 인식하고 왼쪽에 위치하는 “Project Explorer”에서도 아이콘 옆 작은 ‘s’가 붙은 것을 확인할 수 있을 것이다.

이제 JUnit을 이용하여 DB에 접근하여 데이터를 처리할 수 있는지 테스트해야 한다. 이전 포스팅에서는 이미 연결에 관한 테스트는 마쳤기 때문에 DAO 테스트만 하면 될 것 같다.
클래스의 이름은 DaoTest이고 소스는 다음과 같다.
package com.board.first; import javax.inject.Inject; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.board.dao.MemberDAO; import com.board.dto.Member; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/*.xml"}) public class DaoTest { private Logger logger = Logger.getLogger("DAO 테스트"); private Member member; @Inject private MemberDAO dao; @Test public void insertTest() { this.member = new Member(); member.setId("admin"); member.setPw("admin"); member.setName("JongBin"); member.setHp("010-0000-0000"); member.setEmail("jongbin@devbin.kr"); dao.insert(member); logger.info("삽입완료"); } @Test public void selectTest() { logger.info(dao.select("admin").getHp()); logger.info("검색완료"); } @Test public void updateTest() { this.member = dao.select("admin"); this.member.setHp("010-9999-9999"); dao.update(this.member); logger.info("수정완료"); } @Test public void deleteTest() { dao.delete("admin"); logger.info("삭제완료"); } }
여기서 알아두어야 할 점은 JUnit은 테스트를 위 코드의 순서대로 하지 않는다는 점이다. 따라서 오른쪽의 Outline에서 insert 부터 차례대로 실행해야 한다.

테스트 순서는 삽입 검색 수정 검색 삭제 순으로 했다. logger로 찍었으니 console에서 출력값을 확인하면 된다.
여기까지 정리하자면…
- 데이터베이스에 테이블을 정의
- 정의된 테이블을 보며 DTO 작성
- DAO를 작성하기 위해 먼저 MyBATIS의 mapper.xml 파일에 SQL 작성
- DAO 작성
- Spring Framework : POJO를 찾을 수 있게 servlet-context.xml파일에서 “component-scan” 수정하기
- TEST
앞으로 할 일…
- 게시판에 관한 DTO, DAO 작성하기
- View(JSP File) 작성
- CSS / Javascript 작성
- Controller 작성
- TEST