UserDaoTest.java (테스트용 클라이언트 Class)
package springbook.user;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
public class UserDaoTest {
/*
* ApplicationContext 객체를 사용하여 getBean을 이용하여 UserDao에 DI를 주입 할수도 있지만
* Autowired 를 통하여 바로 UserDao에 DI를 주입하는 방법을 통해
* ApplicationContext 객체를 사용하지 않는 방법을 택했다.
*
* @Autowired
* private ApplicationContext context;
*/
@Autowired
private UserDao dao;
private User user1;
private User user2;
private User user3;
@Before
public void setUp() {
/*
* Configuration File인 daoFactory.class 에서 userDao 라는 빈을 가지고 오고 그
* userDao 라는 빈은 UserDao Object를 반환한다.
*/
// this.dao = context.getBean("userDao", UserDao.class);
user1 = new User("SexyGuy", "김성민", "springman1");
user2 = new User("delay", "류민기", "springman2");
user3 = new User("postpone", "송준화", "springman3");
}
public static void main(String[] args) {
JUnitCore.main("springbook.user.UserDaoTest");
}
@Test
public void addAndGet() throws ClassNotFoundException, SQLException {
dao.deleteAll();
assertThat(dao.getCount(), is(0));
dao.deleteAll();
assertThat(dao.getCount(), is(0));
dao.add(user1);
dao.add(user2);
dao.add(user3);
assertThat(dao.getCount(), is(3));
User userget1 = dao.get(user1.getId());
assertThat(userget1.getName(), is(user1.getName()));
assertThat(userget1.getPassword(), is(user1.getPassword()));
User userget2 = dao.get(user2.getId());
assertThat(userget2.getName(), is(user2.getName()));
assertThat(userget2.getPassword(), is(user2.getPassword()));
User userget3 = dao.get(user3.getId());
assertThat(userget3.getName(), is(user3.getName()));
assertThat(userget3.getPassword(), is(user3.getPassword()));
}
@Test(expected = EmptyResultDataAccessException.class)
public void getUserFaiure() throws SQLException, ClassNotFoundException {
dao.deleteAll();
assertThat(dao.getCount(), is(0));
dao.get("unknown_id");
}
}
applicationContext.xml (@Configuration과 @Bean 환경설정 xml)
<beans>
<bean id="userDao" class="springbook.user.dao.UserDao">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
<property name="username" value="scott" />
<property name="password" value="tiger" />
</bean>
</beans>
UserDao.java (의존성 주입을 당할 자바 빈 Class)
public class UserDao {
private DataSource dataSource;
private JdbcContext jdbcContext;
public void setDataSource(DataSource dataSource) {
this.jdbcContext = new JdbcContext();
this.jdbcContext.setDataSource(dataSource);
this.dataSource = dataSource;
}
public void deleteAll() throws SQLException {
this.jdbcContext.executeSql("delete from users");
}
...
}
JdbcContext.java (템플릿과 콜백 패턴을 써서 만든 Class)
public class JdbcContext {
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void workWithStatementStrategy (StatementStrategy stmt) throws SQLException {
Connection c = null;
PreparedStatement ps = null;
try {
c = dataSource.getConnection();
ps = stmt.makePreparedStatement(c);
ps.executeUpdate();
} catch (SQLException e) {
throw e;
} finally {
if (ps != null) { try { ps.close(); } catch (SQLException e) {} }
if (c != null) { try { c.close(); } catch (SQLException e) {} }
}
}
public void executeSql(final String query) throws SQLException {
workWithStatementStrategy( new StatementStrategy() {
@Override
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
return c.prepareStatement(query);
}
});
}
}
StatementStrategy.java (전략 패턴을 써야 함으로 인한 Interface)
public interface StatementStrategy {
PreparedStatement makePreparedStatement(Connection c) throws SQLException;
}