회원 목록 추가

testAdd() 메소드를 만들고 회원 목록을 추가하는 기능을 추가합니다.

public void testAdd() {

       Member member = createMember();
       mr.add(member);
       assertEquals(1, mr.getNumberOfMembers());
}

createMember() 메소드에서 Member 객체를 받아온 뒤 MeberRepository 타입의 변수 mr의 add(Member member) 메소드를 통해서 DB에 Member 객체의 data를 넣어줍니다. 그리고 DB에 정말 들어갔는지 DB에 들어있는 Member Data의 수를 getNumberOfMembers() 메소드를 사용해서 확인합니다.

이 test 클래스에서 두 개의 메소드에 대한 test를 하게 되는 거나 마찬가지기 때문에 별로 test 메소드가 좋아보이지는 않지만 일단 개발을 하고 나중에 리팩토링을 하도록 하겠습니다. 헤헤헷; 일단 getNumberOfMembers() 메소드를 사용하는 부분은 주석처리를 하고 add() 부터 구현합니다.

개발 되는 순서

  1. MemberRepository 인터페이스에 void add(Member member); 이렇게 한 줄을 추가합니다.
  2. MemberRepositoryImple 클래스에 void add(Member member) { memberDao.add(member); } 이렇게 구현합니다.
  3. MemberDao 인터페이스에 void add(Member member); 이렇게 한 줄을 추가합니다.
  4. SqlmapMembeDao 클래스에 void add(Member member){ getSqlMapClientTemplate().insert(“Member.insert”, newMember); } 이렇게 추가합니다.
  5. 여기서 test를 한번 해보면…
  6. Member.xml에서 insert라는 id를 찾을 수 없기 때문에 에러가 발생합니다.
  7. Member.xml에 다음과 같이 sql문을 추가합니다.                                                                 <insert id=”insert” parameterClass=”member”>
           INSERT INTO Member(name, email
           <isNotNull property=”messengerId”>, messengerId</isNotNull>
           <isNotNull property=”phone”>, phone</isNotNull>
           <isNotNull property=”blugAddress”>, blugAddress </isNotNull>)
           VALUES(#name#, #email#
           <isNotNull property=”messengerId”>, #messengerId#</isNotNull>
           <isNotNull property=”phone”>, #phone#</isNotNull>
           <isNotNull property=”blugAddress”>, #blugAddress#</isNotNull>);
       </insert>

이제 주석처리 했던 부분을 제거하고 getNumberOfMembers() 이 메소드도 위의 순서대로 개발을 합니다.

add()를 해도 AbstractTransactionalDataSourceSpringContextTests 이 클래스의 특성상 롤백이 되기 때문에 test가 끝나고 DB에 데이터는 저장되어 있지 않습니다.

관련글 :테스트 코드에서의 중복 제거 작업

XML configuration

MemberRepositoryTest 클래스가 AbstractTransactionalDataSourceSpringContextTests 클래스를 상속 받았을 때오버라이드 해줘야 하는 메소드가 있습니다.

protected String[] getConfigLocations() 메소드입니다. Configuration 파일들의 경로를 string 배열로 반환합니다. 그리고 MemberRespository 타입의 mr이라는 변수를 Spring의 IOC(Inversion of Control)중에 DI(dependency Injection)을 사용하여 new를 사용하지 않고 XML에서 연결할 수가 있는데 그 중에 setter injection을 사용하려면 setMr() 메소드가 있어야 합니다.

소스보기
[#M_ more.. | less.. |
@Override
   protected String[] getConfigLocations() {
       return new String[] {
               “file:conf/applicationContext-member.xml”,
               “file:conf/daoContext.xml”,
               “file:conf/daoContext-member.xml”, };
   }

   public void setMr(MemberRepository mr) {
       this.mr = mr;
   }
_M#]
applicationContext-member.xml 파일 소스보기
[#M_ more.. | less.. |
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
   xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
   xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd”>

   <bean id=”mr”
       class=”net.webapp2.member.service.MemberRepositoryImpl”>
       <property name=”memberDao” ref=”memberDao” />
   </bean>
</beans>
_M#]
daoContext-member.xml 파일 소스보기
[#M_ more.. | less.. |
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
   xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
   xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd”>

   <bean id=”memberDao” class=”net.webapp2.member.dao.SqlmapMemberDao”>
       <property name=”sqlMapClient” ref=”sqlMapClient” />
   </bean>
</beans>
_M#]
daoContext.xml 파일 소스보기
[#M_ more.. | less.. |
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
   xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
   xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>

   <!– DataSource –>
   <!– MySQL –>
   <bean id=”dataSource”
       class=”org.apache.commons.dbcp.BasicDataSource”
       destroy-method=”close”>
       <property name=”driverClassName” value=”com.mysql.jdbc.Driver” />
       <property name=”url” value=”jdbc:mysql://localhost:3306/adressbook?autoReconnect=true” />
       <property name=”username” value=”keesun” />
       <property name=”password” value=”keesun” />
   </bean>

   <!– SqlMap setup for iBATIS Database Layer –>
   <bean id=”sqlMapClient”
       class=”org.springframework.orm.ibatis.SqlMapClientFactoryBean”>
       <property name=”configLocation”
           value=”file:conf/sql-map-config.xml” />
       <property name=”dataSource” ref=”dataSource” />
   </bean>

   <!– Transaction Manager –>
   <bean id=”transactionManager”
       class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
       <property name=”dataSource” ref=”dataSource” />
   </bean>

</beans>
_M#]
그림으로 보면 다음과 같습니다.
1150945885.bmp

MySQL Connector Down + testAdd()

1258680398.bmpJava 소스코드와 MySQL을 연결하기 위한 객체를 생성하려면 JDBC 드라이버가 필요합니다. 드라이버는 다운로드 페이지의 왼쪽 메뉴처럼 클릭하면 다운 받으실 수 있습니다.

다운로드 받은 파일의 압축을 풀면 mysql-connector-java-5.0.4-bin.jar 파일을 볼 수 있습니다. 이 jar파일을 프로젝트에 추가합니다.

spring에서는 DB연결 설정을 XML 파일을 사용하여 설정할 수 있습니다. 그렇게 하려면 org.apache.commons.dbcp.BasicDataSource 이 클래스가 필요한데 이 클래스는 commons-dbcp.jar 파일에 들어있습니다. 이 jar파일은 “Spring 설치 폴더”\lib\jakarta-commons에 들어있습니다.

이제 다시 Eclipse로 돌아가서 MemberRepositoryTest 클래스에 testAdd 메소드를 추가합니다.

소스코드보기
[#M_ more.. | less.. |
public void testAdd() {
       Member member = createMember();
       mr.add(member);
       assertEquals(1, mr.getNumberOfMembers());

       member = createMember();
       mr.add(member);
       assertEquals(2, mr.getNumberOfMembers());

       member = createMember();
       mr.add(member);
       assertEquals(3, mr.getNumberOfMembers());
   }_M#]
MemberRepository mr;
이 멤버 변수를 class에 추가합니다. 그리고 src폴더에 MemberRepository 인터페이스와 이를 구현한 MemberRepositoryImpl 클래스를 추가합니다. MemberRepositoryImpl에서는 MemberDao를 사용하도록 멤버변수를 추가하고 MemberDao 인터페이와 이를 구현한 SqlmapMemberDao 클래스를 만듭니다. 이때 SqlmapMemberDao는 SqlMapClientDaoSupport를 상속 받도록 하여 xml을 사용하여 sql 쿼리를 보내고 결과를 받아올 수 있습니다.

1032444174.bmp
클래스는 이러한 구조로 이루어집니다. SqlMapclientDaoSupport 클래스는 Spring.jar안에 들어있기 때문에 따로 특정 jar파일을 프로젝트에 추가할 필요는 없습니다.

MySQL 설치 + 사용

다운로드 페이지에서 두 가지 중에 하나를 선택할 수 가 있는데 여기서 Community Server의 download를 클릭합니다.

Windows Essentials (x86)을 다운로드 받고 설치를 했습니다. 그리고 GUI 툴을 다운받고 설치 합니다.

1116503943.bmp
New User 버튼을 클릭해서 새로운 사용자를 추가합니다.

1280310865.bmp새로운 DB를 만들려면 Catalogs를 클릭하고 하단의 빈 부분에서 마우스 오른쪽 버튼을 클릭하고 Create New Schema를 선택합니다.

현재는 root 계정으로 로그인 하여 DB를 만들었기 때문에 조금 전에 만들었던 사용자계정에게 이 DB를 관리 할 수 있는 권한을 주어야 합니다.

특정 사용자에게 특정 DB의 특정 권한을 주고 싶다면 User Administration을 클릭한 뒤 권한을 주고자 하는 사용자를 선택하고 -> DB를 선택하고 -> 권한을 선택하고 -> Assigned Privilege로 옮겨 줍니다.

1400299477.bmp

프로젝트 생성 + jar 파일 추가

요구 사항 인터뷰를 들은 것은 이번주 월요일(11월 6일) 입니다. 그리고 오늘은 목요일(11월 9일)입니다.

월요일에 신나서 코딩을 한답시고 쭉~~~했습니다. 시작하자 마자 의문점이 생겼습니다. ‘Member를 가져오려면 먼저 저장이 되어 있어야 되는것 아닌가?’ 였습니다. 그럼 먼저 Member 객체의 정보를 DB에 저장하는 것 부터 만들어야 겠구나.. 라고 결론 지었습니다.

그렇게 생각을 정리하고 먼저 Eclipse에서 프로젝트를 생성하기 시작했습니다.

1140880315.bmp프로젝트 이름은 addressbook으로 생성하고 소스폴더로 src와 test를 만들었습니다.

그리고 xml configuration metadata 파일들을 한 곳에 두려고 conf라는 폴더를 만들었으며 필요한 jar 파일들을 절대 경로가 아니라 lib 이라는 폴더에서 가져 가도록 상대 경로를 사용할 수 있게 일단 폴더만 만들어 두었습니다.

이렇게 폴더만 만들어 둔 상태에서 무엇을 해야 할까 고민을 하던 중 일단 src 밑에 Member.java 라는 도메인 역할을 하는 클래스 부터 만들기로 생각하고 그 메소드를 test할 MemberTest.java 파일을 test 폴더 밑에 net.webapp2.member에 만들었습니다.

그렇게 MemberTest.java와 Member.java 파일을 만들고 나서 MemberRepositotyTest.java 파일을 생성하고 testAdd() 메소드를 추가하였습니다.

Agile java 책에서 배운 TDD를 쪼~금 이나마 적용해 보았는데 역시나 적응이 쉽지 않았습니다.

일단 이렇게 껍데기를 만드는데도 상당한 시간이 소모되었습니다. 제일 시간이 많이 소요된 시점은 MemberRepositoryTest 클래스를 만드는 부분이였습니다. test 메소드 후에 test를 하면서 발생했던 트랜잭션을 롤백 해주는 클래스인 AbstractTransactionalDataSourceSpringContextTests 클래스를 상속받아야 했습니다. 이 클래스는 org.springframework.test 패키지에 있으며 이 패키지는 spring-mock.jar 파일에 있습니다. 이 파일은 “spring을 설치한 폴더”\dist 안에 있습니다.

1202077778.bmp

상대경로로 Jar 파일 추가하기

dist폴더 안에 있는 jar 파일을 eclipse의 프로젝트에 추가하는 방법은 프로젝트를 우클릭->맨 아래 프로퍼티s-> Java Build Path에서 Add External Jar File을 클릭하여 추가할 수 있습니다. BUT!!! 이렇게 jar파일을 추가하면 절대 경로로 참조하게 되어 이 프로젝트를 다른 개발자들과 공유를 했을 때 문제가 생기게 됩니다. 따라서 lib폴더로 jar파일을 복사 해두고 Java Build Path에서 Add Jar Field을 클릭하여 addressbook 프로젝트의 lib폴더에 복사 해둔 jar파일을 추가합니다. 이렇게 하면 lib 폴더 안에 있는 jar 파일을 참조하게 되기 때문에 이 프로젝트를 다른 개발자들과 공유를 하더라도 lib폴더에 있는 jar파일도 같이 공유가 되고 lib 폴더를 참조하게 되어 있기 때문에 문제가 발생하지 않습니다.

1105273732.bmp

ps : google code의 springkorea 프로젝트의 svn에 올려 두었습니다. http://springkorea.google.com/svn 에서 checkout 받으실 수 있습니다.