Skip to content

Commit

Permalink
[JDBC 라이브러리 구현 3,4단계] 리오(오영택) 미션 제출합니다. (#574)
Browse files Browse the repository at this point in the history
* test: 학습테스트1 작성

* test: 학습테스트2 작성

* feat: 트랜잭션 구현

* feat: 서비스 분리

* feat: 서비스 분리

* feat: deleteAll 구현

* refactor: 조회시에도 트랜잭션 설정

* fix: 예외사항 추가

* chore: 개행 삭제

* fix: 트랜잭션 안에서 같은 커넥션을 사용하도록 수정

* refactor: 커넥션을 닫는 로직 변경

* test: 테스트 변경
  • Loading branch information
Jaeyoung22 authored Oct 10, 2023
1 parent 738e00e commit e2e7412
Show file tree
Hide file tree
Showing 19 changed files with 367 additions and 160 deletions.
6 changes: 6 additions & 0 deletions app/src/main/java/com/techcourse/dao/UserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@ public User findByAccount(String account) {
}
return user.get();
}

public void deleteAll() {
String sql = "delete from users";

jdbcTemplate.update(sql);
}
}
36 changes: 36 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,36 @@
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(long id) {
return userDao.findById(id);
}

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

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

userDao.update(user);
userHistoryDao.log(new UserHistory(user, createBy));
}
}
34 changes: 34 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,34 @@
package com.techcourse.service;

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

import java.util.concurrent.atomic.AtomicReference;

public class TxUserService implements UserService {

private final UserService userService;
private final TransactionTemplate transactionTemplate;

public TxUserService(UserService userService, TransactionTemplate transactionTemplate) {
this.userService = userService;
this.transactionTemplate = transactionTemplate;
}

@Override
public User findById(long id) {
AtomicReference<User> user = new AtomicReference<>();
transactionTemplate.execute(() -> user.set(userService.findById(id)));
return user.get();
}

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

@Override
public void changePassword(long id, String newPassword, String createBy) {
transactionTemplate.execute(() -> userService.changePassword(id, newPassword, createBy));
}
}
28 changes: 4 additions & 24 deletions app/src/main/java/com/techcourse/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
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 UserService {
public interface UserService {

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

public UserService(UserDao userDao, UserHistoryDao userHistoryDao) {
this.userDao = userDao;
this.userHistoryDao = userHistoryDao;
}
void insert(User user);

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

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

public void changePassword(long id, String newPassword, String createBy) {
User user = findById(id);
user.changePassword(newPassword);
userDao.update(user);
userHistoryDao.log(new UserHistory(user, createBy));
}
void changePassword(long id, String newPassword, String createBy);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public static void execute(DataSource dataSource) {
URL url = DatabasePopulatorUtils.class.getClassLoader().getResource("schema.sql");
File file = new File(url.getFile());
String sql = Files.readString(file.toPath());

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(sql);
} catch (IOException | NullPointerException e) {
Expand Down
12 changes: 8 additions & 4 deletions app/src/test/java/com/techcourse/dao/UserDaoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
class UserDaoTest {

private UserDao userDao;
private User user;

@BeforeEach
void setup() {
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());

userDao = new UserDao(DataSourceConfig.getInstance());
userDao.deleteAll();
final var user = new User("gugu", "password", "[email protected]");
userDao.insert(user);
this.user = userDao.findByAccount("gugu");
}

@Test
Expand All @@ -30,7 +33,7 @@ void findAll() {

@Test
void findById() {
final var user = userDao.findById(1L);
final var user = userDao.findById(this.user.getId());

assertThat(user.getAccount()).isEqualTo("gugu");
}
Expand All @@ -48,21 +51,22 @@ void insert() {
final var account = "insert-gugu";
final var user = new User(account, "password", "[email protected]");
userDao.insert(user);
User insertedUser = userDao.findByAccount(account);

final var actual = userDao.findById(2L);
final var actual = userDao.findById(insertedUser.getId());

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

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

userDao.update(user);

final var actual = userDao.findById(1L);
final var actual = userDao.findById(user.getId());

assertThat(actual.getPassword()).isEqualTo(newPassword);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,41 @@
import com.techcourse.dao.UserHistoryDao;
import com.techcourse.domain.User;
import com.techcourse.support.jdbc.init.DatabasePopulatorUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;

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

@Disabled
class UserServiceTest {
class AppUserServiceTest {

private JdbcTemplate jdbcTemplate;
private UserDao userDao;
private User user;

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

DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());
userDao.deleteAll();

final var user = new User("gugu", "password", "[email protected]");
userDao.insert(user);
this.user = userDao.findByAccount("gugu");
}

@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";
userService.changePassword(1L, newPassword, createBy);
userService.changePassword(user.getId(), newPassword, createBy);

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

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

@Test
void testTransactionRollback() {
// 트랜잭션 롤백 테스트를 위해 mock으로 교체
final var userHistoryDao = new MockUserHistoryDao(jdbcTemplate);
final var userService = new UserService(userDao, userHistoryDao);

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

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

assertThat(actual.getPassword()).isNotEqualTo(newPassword);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

public class MockUserHistoryDao extends UserHistoryDao {
Expand All @@ -13,6 +13,7 @@ public MockUserHistoryDao(final JdbcTemplate jdbcTemplate) {

@Override
public void log(final UserHistory userHistory) {
System.out.println("asdf");
throw new DataAccessException();
}
}
58 changes: 58 additions & 0 deletions app/src/test/java/com/techcourse/service/TxUserServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.techcourse.service;

import com.techcourse.config.DataSourceConfig;
import com.techcourse.dao.UserDao;
import com.techcourse.domain.User;
import com.techcourse.support.jdbc.init.DatabasePopulatorUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;

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

class TxUserServiceTest {

private JdbcTemplate jdbcTemplate;
private UserDao userDao;
private TransactionTemplate transactionTemplate;
private User user;

@BeforeEach
void setUp() {
DataSource dataSource = DataSourceConfig.getInstance();

DatabasePopulatorUtils.execute(dataSource);
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.userDao = new UserDao(jdbcTemplate);
this.transactionTemplate = new TransactionTemplate(dataSource);

userDao.deleteAll();


final var user = new User("gugu", "password", "[email protected]");
userDao.insert(user);
this.user = userDao.findByAccount("gugu");
}

@Test
void testTransactionRollback() {
final var userHistoryDao = new MockUserHistoryDao(jdbcTemplate);
final var appUserService = new AppUserService(userDao, userHistoryDao);
final var userService = new TxUserService(appUserService, transactionTemplate);

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

assertThrows(DataAccessException.class,
() -> userService.changePassword(user.getId(), newPassword, createBy));

final var actual = userService.findById(user.getId());

assertThat(actual.getPassword()).isNotEqualTo(newPassword);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.springframework.dao;
package org.springframework;

public class DataAccessException extends RuntimeException {

Expand Down
Loading

0 comments on commit e2e7412

Please sign in to comment.