Skip to content

Commit

Permalink
feat: 커넥션 객체를 JdbcTemplate이 관리하도록 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
gitchannn committed Oct 10, 2023
1 parent 002529c commit e8eba25
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 78 deletions.
27 changes: 13 additions & 14 deletions app/src/main/java/com/techcourse/dao/UserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.List;
import java.util.Optional;

Expand All @@ -24,33 +23,33 @@ public UserDao(final DataSource dataSource) {
this(new JdbcTemplate(dataSource));
}

public void insert(final Connection conn, final User user) {
public void insert(final User user) {
final var sql = "insert into users (account, password, email) values (?, ?, ?)";
jdbcTemplate.update(conn, sql, user.getAccount(), user.getPassword(), user.getEmail());
jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail());
}

public void update(final Connection conn, final User user) {
public void update(final User user) {
final var sql = "UPDATE users SET account = ?, password = ?, email = ? WHERE id = ?";
jdbcTemplate.update(conn, sql, user.getAccount(), user.getPassword(), user.getEmail(), user.getId());
jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail(), user.getId());
}

public List<User> findAll(final Connection conn) {
public List<User> findAll() {
final var sql = "SELECT * FROM users";
return jdbcTemplate.query(conn, sql, User.class);
return jdbcTemplate.query(sql, User.class);
}

public Optional<User> findById(final Connection conn, final Long id) {
public Optional<User> findById(final Long id) {
final var sql = "select id, account, password, email from users where id = ?";
return Optional.of(jdbcTemplate.queryForObject(conn, sql, User.class, id));
return Optional.of(jdbcTemplate.queryForObject(sql, User.class, id));
}

public Optional<User> findByAccount(final Connection conn, final String account) {
public Optional<User> findByAccount(final String account) {
final var sql = "select id, account, password, email from users where account = ?";
return Optional.of(jdbcTemplate.queryForObject(conn, sql, User.class, account));
return Optional.of(jdbcTemplate.queryForObject(sql, User.class, account));
}

public void deleteAll(final Connection conn) {
jdbcTemplate.update(conn, "TRUNCATE TABLE user_history RESTART IDENTITY;");
jdbcTemplate.update(conn, "TRUNCATE TABLE users RESTART IDENTITY");
public void deleteAll() {
jdbcTemplate.update("TRUNCATE TABLE user_history RESTART IDENTITY;");
jdbcTemplate.update("TRUNCATE TABLE users RESTART IDENTITY");
}
}
4 changes: 1 addition & 3 deletions app/src/main/java/com/techcourse/dao/UserHistoryDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.sql.Connection;

public class UserHistoryDao {

Expand All @@ -22,10 +21,9 @@ public UserHistoryDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void log(final Connection conn, final UserHistory userHistory) {
public void log(final UserHistory userHistory) {
final var sql = "insert into user_history (user_id, account, password, email, created_at, created_by) values (?, ?, ?, ?, ?, ?)";
jdbcTemplate.update(
conn,
sql,
userHistory.getUserId(),
userHistory.getAccount(),
Expand Down
24 changes: 6 additions & 18 deletions app/src/main/java/com/techcourse/service/AppUserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public AppUserService(
}

@Override
public User findById(final long id) throws SQLException {
return userDao.findById(dataSource.getConnection(), id)
public User findById(final long id) {
return userDao.findById(id)
.orElseThrow(() -> new NoSuchElementException("해당 아이디의 사용자가 존재하지 않습니다."));
}

Expand All @@ -39,7 +39,7 @@ public void insert(final User user) throws SQLException {
final Connection conn = DataSourceUtils.getConnection(dataSource);
conn.setAutoCommit(false);
try {
userDao.insert(conn, user);
userDao.insert(user);

conn.commit();
} catch (SQLException e) {
Expand All @@ -51,22 +51,10 @@ public void insert(final User user) throws SQLException {
}

@Override
public void changePassword(final long id, final String newPassword, final String createBy) throws SQLException {
final Connection conn = DataSourceUtils.getConnection(dataSource);
conn.setAutoCommit(false);
public void changePassword(final long id, final String newPassword, final String createBy) {
final var user = findById(id);
user.changePassword(newPassword);
try {
userDao.update(conn, user);
userHistoryDao.log(conn, new UserHistory(user, createBy));

conn.commit();
} catch (SQLException | DataAccessException e) {
System.out.println("e = " + e);
conn.rollback();
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(conn, dataSource);
}
userDao.update(user);
userHistoryDao.log(new UserHistory(user, createBy));
}
}
22 changes: 17 additions & 5 deletions app/src/main/java/com/techcourse/service/TxUserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.techcourse.domain.User;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.sql.Connection;
Expand All @@ -21,19 +22,28 @@ public TxUserService(
}

@Override
public User findById(final long id) throws SQLException {
public User findById(final long id) {
final Connection conn = DataSourceUtils.getConnection(dataSource);
conn.setAutoCommit(false);
try {
conn.setAutoCommit(false);
final User user = userService.findById(id);

conn.commit();
return user;
} catch (SQLException e) {
conn.rollback();
rollback(conn);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(conn, dataSource);
TransactionSynchronizationManager.unbindResource(dataSource);
}
}

private void rollback(final Connection conn) {
try {
conn.rollback();
} catch (SQLException e) {
throw new DataAccessException(e);
}
}

Expand All @@ -46,10 +56,11 @@ public void insert(final User user) throws SQLException {

conn.commit();
} catch (SQLException e) {
conn.rollback();
rollback(conn);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(conn, dataSource);
TransactionSynchronizationManager.unbindResource(dataSource);
}
}

Expand All @@ -62,10 +73,11 @@ public void changePassword(final long id, final String newPassword, final String

conn.commit();
} catch (SQLException e) {
conn.rollback();
rollback(conn);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(conn, dataSource);
TransactionSynchronizationManager.unbindResource(dataSource);
}
}
}
21 changes: 10 additions & 11 deletions app/src/test/java/com/techcourse/dao/UserDaoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ void setup() throws SQLException {

userDao = new UserDao(DataSourceConfig.getInstance());
final var user = new User("gitchan", "password", "[email protected]");
userDao.insert(conn, user);
userDao.insert(user);
}

@AfterEach
void tearDown() {
userDao.deleteAll(conn);
userDao.deleteAll();
}

@Test
void findAll() {
final var users = userDao.findAll(conn);
final var users = userDao.findAll();

assertAll(
() -> assertThat(users).isNotEmpty(),
Expand All @@ -47,7 +47,7 @@ void findAll() {

@Test
void findById() {
final var findUser = userDao.findById(conn, 1L).get();
final var findUser = userDao.findById(1L).get();

assertAll(
() -> assertThat(findUser.getAccount()).isEqualTo("gitchan"),
Expand All @@ -58,8 +58,7 @@ void findById() {

@Test
void findByAccount() {
final String account = "gitchan";
final User findUser = userDao.findByAccount(conn, account).get();
final User findUser = userDao.findByAccount("gitchan").get();

assertAll(
() -> assertThat(findUser.getAccount()).isEqualTo("gitchan"),
Expand All @@ -72,22 +71,22 @@ void findByAccount() {
void insert() {
final var account = "insert-gitchan";
final var user = new User(account, "password", "[email protected]");
userDao.insert(conn, user);
userDao.insert(user);

final var actual = userDao.findById(conn, 2L).get();
final var actual = userDao.findById(2L).get();

assertThat(actual.getAccount()).isEqualTo(account);
}

@Test
void update() {
final var newPassword = "password99";
final var user = userDao.findById(conn, 1L).get();
final var user = userDao.findById(1L).get();
user.changePassword(newPassword);

userDao.update(conn, user);
userDao.update(user);

final var actual = userDao.findById(conn, 1L).get();
final var actual = userDao.findById(1L).get();

assertThat(actual.getPassword()).isEqualTo(newPassword);
}
Expand Down
18 changes: 9 additions & 9 deletions app/src/test/java/com/techcourse/service/AppUserServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.SQLException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

Expand All @@ -21,42 +19,44 @@ class AppUserServiceTest {
private UserDao userDao;

@BeforeEach
void setUp() throws SQLException {
void setUp() {
this.jdbcTemplate = new JdbcTemplate(DataSourceConfig.getInstance());
this.userDao = new UserDao(jdbcTemplate);

DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());
final var user = new User("gugu", "password", "[email protected]");
userDao.insert(jdbcTemplate.getDataSource().getConnection(), user);
userDao.insert(user);
}

@Test
void testChangePassword() throws SQLException {
void testChangePassword() {
final var userHistoryDao = new UserHistoryDao(jdbcTemplate);
final var userService = new AppUserService(userDao, userHistoryDao, jdbcTemplate.getDataSource());
final var appUserService = new AppUserService(userDao, userHistoryDao, jdbcTemplate.getDataSource());
final TxUserService userService = new TxUserService(jdbcTemplate.getDataSource(), appUserService);

final var newPassword = "qqqqq";
final var createBy = "gugu";
userService.changePassword(1L, newPassword, createBy);
appUserService.changePassword(1L, newPassword, createBy);

final var actual = userService.findById(1L);

assertThat(actual.getPassword()).isEqualTo(newPassword);
}

@Test
void testTransactionRollback() throws SQLException {
void testTransactionRollback() {
// 트랜잭션 롤백 테스트를 위해 mock으로 교체
final MockUserHistoryDao userHistoryDao = new MockUserHistoryDao(jdbcTemplate);
final AppUserService appUserService = new AppUserService(userDao, userHistoryDao, jdbcTemplate.getDataSource());
final TxUserService userService = new TxUserService(jdbcTemplate.getDataSource(), appUserService);

final var newPassword = "newPassword";
final var createBy = "gugu";

// 트랜잭션이 정상 동작하는지 확인하기 위해 의도적으로 MockUserHistoryDao에서 예외를 발생시킨다.
assertThrows(
DataAccessException.class,
() -> appUserService.changePassword(1L, newPassword, createBy)
() -> userService.changePassword(1L, newPassword, createBy)
);

final var actual = appUserService.findById(1L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.Connection;

public class MockUserHistoryDao extends UserHistoryDao {

public MockUserHistoryDao(final JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}

@Override
public void log(final Connection conn, final UserHistory userHistory) {
public void log(final UserHistory userHistory) {
throw new DataAccessException();
}
}
Loading

0 comments on commit e8eba25

Please sign in to comment.