Skip to content

Commit

Permalink
[JDBC 라이브러리 구현하기 - 4단계] 준팍(박준현) 미션 제출합니다. (#607)
Browse files Browse the repository at this point in the history
  • Loading branch information
junpakPark authored Oct 18, 2023
1 parent 87a4d76 commit f3f43a7
Show file tree
Hide file tree
Showing 14 changed files with 395 additions and 134 deletions.
7 changes: 0 additions & 7 deletions app/src/main/java/com/techcourse/dao/UserDao.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.techcourse.dao;

import com.techcourse.domain.User;
import java.sql.Connection;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
Expand Down Expand Up @@ -41,12 +40,6 @@ public void update(final User user) {
jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail());
}

public void update(Connection connection, User user) {
final var sql = "update users set account = ?, password = ?, email = ? ";

jdbcTemplate.update(connection, sql, user.getAccount(), user.getPassword(), user.getEmail());
}

public List<User> findAll() {
final var sql = "select id, account, password, email from users ";

Expand Down
15 changes: 0 additions & 15 deletions app/src/main/java/com/techcourse/dao/UserHistoryDao.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.techcourse.dao;

import com.techcourse.domain.UserHistory;
import java.sql.Connection;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;

Expand Down Expand Up @@ -31,18 +30,4 @@ public void log(final UserHistory userHistory) {
);
}

public void log(Connection connection, UserHistory userHistory) {
final var sql = "insert into user_history (user_id, account, password, email, created_at, created_by) values (?, ?, ?, ?, ?, ?)";

jdbcTemplate.update(
connection,
sql,
userHistory.getUserId(),
userHistory.getAccount(),
userHistory.getPassword(),
userHistory.getEmail(),
userHistory.getCreatedAt(),
userHistory.getCreateBy()
);
}
}
37 changes: 37 additions & 0 deletions app/src/main/java/com/techcourse/service/AppUserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.techcourse.service;

import com.techcourse.dao.UserDao;
import com.techcourse.dao.UserHistoryDao;
import com.techcourse.domain.User;
import com.techcourse.domain.UserHistory;

public class AppUserService implements UserService {

private final UserDao userDao;
private final UserHistoryDao userHistoryDao;

public AppUserService(UserDao userDao, UserHistoryDao userHistoryDao) {
this.userDao = userDao;
this.userHistoryDao = userHistoryDao;
}

@Override
public User findById(final long id) {
return userDao.findById(id);
}

@Override
public void insert(final User user) {
userDao.insert(user);
}

@Override
public void changePassword(long id, String newPassword, String createBy) {
final var user = findById(id);
user.changePassword(newPassword);

userDao.update(user);
userHistoryDao.log(new UserHistory(user, createBy));
}

}
31 changes: 31 additions & 0 deletions app/src/main/java/com/techcourse/service/TxUserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.techcourse.service;

import com.techcourse.domain.User;
import org.springframework.transaction.support.TransactionManager;

public class TxUserService implements UserService {

private final TransactionManager transactionManager;
private final UserService userService;

public TxUserService(TransactionManager transactionManager, UserService userService) {
this.transactionManager = transactionManager;
this.userService = userService;
}

@Override
public User findById(long id) {
return transactionManager.query(() -> userService.findById(id));
}

@Override
public void insert(User user) {
transactionManager.execute(() -> userService.insert(user));
}


@Override
public void changePassword(long id, String newPassword, String createBy) {
transactionManager.execute(() -> userService.changePassword(id, newPassword, createBy));
}
}
72 changes: 4 additions & 68 deletions app/src/main/java/com/techcourse/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,76 +1,12 @@
package com.techcourse.service;

import com.techcourse.config.DataSourceConfig;
import com.techcourse.dao.UserDao;
import com.techcourse.dao.UserHistoryDao;
import com.techcourse.domain.User;
import com.techcourse.domain.UserHistory;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;

public class UserService {
public interface UserService {

private final UserDao userDao;
private final UserHistoryDao userHistoryDao;
User findById(final long id);

public UserService(final UserDao userDao, final UserHistoryDao userHistoryDao) {
this.userDao = userDao;
this.userHistoryDao = userHistoryDao;
}

public User findById(final long id) {
return userDao.findById(id);
}

public void insert(final User user) {
userDao.insert(user);
}

public void changePassword(final long id, final String newPassword, final String createBy) {
final var user = findById(id);
user.changePassword(newPassword);

DataSource dataSource = DataSourceConfig.getInstance();
Connection connection = null;

try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);

userDao.update(connection, user);
userHistoryDao.log(connection, new UserHistory(user, createBy));

connection.commit();
} catch (RuntimeException | SQLException e) {
rollback(connection);
throw new DataAccessException(e);
} finally {
close(connection);
}
}

private void rollback(Connection connection) {
if (connection == null) {
return;
}
try {
connection.rollback();
} catch (final SQLException e) {
throw new DataAccessException(e);
}
}

private void close(final Connection connection) {
if (connection == null) {
return;
}
try {
connection.close();
} catch (final SQLException e) {
throw new DataAccessException(e);
}
}
void insert(final User user);

void changePassword(final long id, final String newPassword, final String createBy);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ public static void execute(final DataSource dataSource) {
if (statement != null) {
statement.close();
}
} catch (SQLException ignored) {}
} catch (SQLException e) {
log.warn(String.valueOf(e));
}

try {
if (connection != null) {
connection.close();
}
} catch (SQLException ignored) {}
} catch (SQLException e) {
log.warn(String.valueOf(e));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.techcourse.dao.UserHistoryDao;
import com.techcourse.domain.UserHistory;
import java.sql.Connection;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

Expand All @@ -17,8 +16,4 @@ public void log(final UserHistory userHistory) {
throw new DataAccessException();
}

@Override
public void log(Connection connection, UserHistory userHistory) {
throw new DataAccessException();
}
}
10 changes: 8 additions & 2 deletions app/src/test/java/com/techcourse/service/UserServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.junit.jupiter.api.Test;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.support.TransactionManager;

class UserServiceTest {

Expand All @@ -31,7 +32,7 @@ void setUp() {
@Test
void testChangePassword() {
final var userHistoryDao = new UserHistoryDao(jdbcTemplate);
final var userService = new UserService(userDao, userHistoryDao);
final var userService = new AppUserService(userDao, userHistoryDao);

final var newPassword = "qqqqq";
final var createBy = "gugu";
Expand All @@ -46,7 +47,12 @@ void testChangePassword() {
void testTransactionRollback() {
// 트랜잭션 롤백 테스트를 위해 mock으로 교체
final var userHistoryDao = new MockUserHistoryDao(jdbcTemplate);
final var userService = new UserService(userDao, userHistoryDao);
// 애플리케이션 서비스
final var appUserService = new AppUserService(userDao, userHistoryDao);
TransactionManager transactionManager = new TransactionManager(DataSourceConfig.getInstance());

// 트랜잭션 서비스 추상화
final var userService = new TxUserService(transactionManager,appUserService);

final var newPassword = "newPassword";
final var createBy = "gugu";
Expand Down
54 changes: 24 additions & 30 deletions jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.datasource.DataSourceUtils;

public class JdbcTemplate {

Expand All @@ -24,8 +25,9 @@ public JdbcTemplate(final DataSource dataSource) {
}

public void update(final String sql, final Object... args) {
Connection connection = DataSourceUtils.getConnection(dataSource);

try (
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)
) {
log.debug(QUERY_FORMAT, sql);
Expand All @@ -37,20 +39,11 @@ public void update(final String sql, final Object... args) {
}
}

public void update(Connection connection, String sql, Object... args) {
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
log.debug(QUERY_FORMAT, sql);

bindStatementWithArgs(args, preparedStatement);
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new DataAccessException(e);
}
}

public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... args) {
Connection connection = DataSourceUtils.getConnection(dataSource);

try (
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = getPreparedStatement(connection, sql, args);
ResultSet resultSet = preparedStatement.executeQuery()
) {
Expand All @@ -68,26 +61,10 @@ public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMa
}
}

private PreparedStatement getPreparedStatement(
Connection connection,
String sql,
Object[] args
) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
bindStatementWithArgs(args, preparedStatement);

return preparedStatement;
}

private void bindStatementWithArgs(Object[] args, PreparedStatement preparedStatement) throws SQLException {
for (int i = 1; i <= args.length; i++) {
preparedStatement.setObject(i, args[i - 1]);
}
}

public <T> List<T> query(final String sql, final RowMapper<T> rowMapper) {
Connection connection = DataSourceUtils.getConnection(dataSource);

try (
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery()
) {
Expand All @@ -106,4 +83,21 @@ public <T> List<T> query(final String sql, final RowMapper<T> rowMapper) {
}
}

private PreparedStatement getPreparedStatement(
Connection connection,
String sql,
Object[] args
) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
bindStatementWithArgs(args, preparedStatement);

return preparedStatement;
}

private void bindStatementWithArgs(Object[] args, PreparedStatement preparedStatement) throws SQLException {
for (int i = 1; i <= args.length; i++) {
preparedStatement.setObject(i, args[i - 1]);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.springframework.transaction;

public class TransactionException extends RuntimeException {

public TransactionException(Exception e) {
super(e);
}

}
Loading

0 comments on commit f3f43a7

Please sign in to comment.