Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JDBC 라이브러리 구현하기 - 1단계] 성하(김성훈) 미션 제출합니다. #311

Merged
merged 6 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 30 additions & 88 deletions app/src/main/java/com/techcourse/dao/UserDao.java
Original file line number Diff line number Diff line change
@@ -1,121 +1,63 @@
package com.techcourse.dao;

import com.techcourse.domain.User;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

public class UserDao {

private static final Logger log = LoggerFactory.getLogger(UserDao.class);

private final DataSource dataSource;

public UserDao(final DataSource dataSource) {
this.dataSource = dataSource;
}
private final JdbcTemplate jdbcTemplate;
private final RowMapper<User> rowMapper = (rs, rowNum) ->
new User(
rs.getLong("id"),
rs.getString("account"),
rs.getString("password"),
rs.getString("email")
);

public UserDao(final JdbcTemplate jdbcTemplate) {
this.dataSource = null;
this.jdbcTemplate = jdbcTemplate;
}

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

Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = dataSource.getConnection();
pstmt = conn.prepareStatement(sql);

log.debug("query : {}", sql);

pstmt.setString(1, user.getAccount());
pstmt.setString(2, user.getPassword());
pstmt.setString(3, user.getEmail());
pstmt.executeUpdate();
} catch (SQLException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException ignored) {}

try {
if (conn != null) {
conn.close();
}
} catch (SQLException ignored) {}
}
jdbcTemplate.update(sql, account, password, email);
}

public void update(final User user) {
// todo
final var sql = "update users set account = ?, password = ?, email = ? where id = ?";
final String account = user.getAccount();
final String password = user.getPassword();
final String email = user.getEmail();
final long id = user.getId();

jdbcTemplate.update(sql, account, password, email, id);
}

public List<User> findAll() {
// todo
return null;
final var sql = "select * from users";

return jdbcTemplate.query(sql, rowMapper);
}

public User findById(final Long id) {
final var sql = "select id, account, password, email from users where id = ?";

Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setLong(1, id);
rs = pstmt.executeQuery();

log.debug("query : {}", sql);

if (rs.next()) {
return new User(
rs.getLong(1),
rs.getString(2),
rs.getString(3),
rs.getString(4));
}
return null;
} catch (SQLException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ignored) {}

try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException ignored) {}

try {
if (conn != null) {
conn.close();
}
} catch (SQLException ignored) {}
}
return jdbcTemplate.queryForObject(sql, rowMapper, id);
}

public User findByAccount(final String account) {
// todo
return null;
final var sql = "select id, account, password, email from users where account = ?";

return jdbcTemplate.queryForObject(sql, rowMapper, account);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.techcourse.config.DataSourceConfig;
import com.techcourse.support.jdbc.init.DatabasePopulatorUtils;
import com.techcourse.support.jdbc.init.ResourceNames;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
Expand All @@ -11,6 +12,6 @@ public class ContextLoaderListener implements ServletContextListener {

@Override
public void contextInitialized(final ServletContextEvent sce) {
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance(), ResourceNames.SCHEMA_RESOURCE_NAME);
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package com.techcourse.support.jdbc.init;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DatabasePopulatorUtils {

private static final Logger log = LoggerFactory.getLogger(DatabasePopulatorUtils.class);

public static void execute(final DataSource dataSource) {
public static void execute(final DataSource dataSource, final String resourceName) {
Connection connection = null;
Statement statement = null;
try {
final var url = DatabasePopulatorUtils.class.getClassLoader().getResource("schema.sql");
final var url = DatabasePopulatorUtils.class.getClassLoader().getResource(resourceName);
final var file = new File(url.getFile());
final var sql = Files.readString(file.toPath());
connection = dataSource.getConnection();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.techcourse.support.jdbc.init;

public class ResourceNames {

public static final String SCHEMA_RESOURCE_NAME = "schema.sql";
public static final String TRUNCATE_RESOURCE_NAME = "truncate.sql";
}
21 changes: 13 additions & 8 deletions app/src/test/java/com/techcourse/dao/UserDaoTest.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
package com.techcourse.dao;

import static org.assertj.core.api.Assertions.assertThat;

import com.techcourse.config.DataSourceConfig;
import com.techcourse.domain.User;
import com.techcourse.support.jdbc.init.DatabasePopulatorUtils;
import com.techcourse.support.jdbc.init.ResourceNames;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import org.springframework.jdbc.core.JdbcTemplate;

class UserDaoTest {

private UserDao userDao;

@BeforeEach
void setup() {
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance(), ResourceNames.SCHEMA_RESOURCE_NAME);
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance(), ResourceNames.TRUNCATE_RESOURCE_NAME);

Comment on lines 18 to 21

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

truncate 👍 👍

userDao = new UserDao(DataSourceConfig.getInstance());
userDao = new UserDao(new JdbcTemplate(DataSourceConfig.getInstance()));
final var user = new User("gugu", "password", "[email protected]");
userDao.insert(user);
}
Expand All @@ -30,9 +33,11 @@ void findAll() {

@Test
void findById() {
final var user = userDao.findById(1L);
final var user = userDao.findAll().get(0);
Comment on lines 35 to +36

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@beforeeach에서 유저를 insert할때 id값도 1로 지정해서 넣어주면 어떨까요??

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다시 봐보니 findById 메소드 테스트인데 findById를 사용하지 않고 있었네요 ㅠㅠ

루쿠가 말해주신 @BeforeEach에서 유저의 ID를 1로 지정하고 전체 테스트를 수행했을 때
엔티티의 ID를 1로 넣는다고 해서 고정이 되지 않더라구요!

insert해서 DB에 들어가는 ID는 Auto Increment라서 엔티티의 ID 필드와 상관없이 조회 시에 DB PK를 가져오기 때문에
1씩 증가한 ID를 가져오는 것 같아요!

그래서 @BeforeEach는 그대로 놔두고, 테스트에서 findById를 사용하는 식으로 리팩토링했습니다!!

long userId = user.getId();
User findUser = userDao.findById(userId);

assertThat(user.getAccount()).isEqualTo("gugu");
assertThat(findUser.getAccount()).isEqualTo("gugu");
}

@Test
Expand All @@ -57,12 +62,12 @@ void insert() {
@Test
void update() {
final var newPassword = "password99";
final var user = userDao.findById(1L);
final var user = userDao.findAll().get(0);
user.changePassword(newPassword);

userDao.update(user);

final var actual = userDao.findById(1L);
final var actual = userDao.findAll().get(0);

assertThat(actual.getPassword()).isEqualTo(newPassword);
}
Expand Down
13 changes: 7 additions & 6 deletions app/src/test/java/com/techcourse/service/UserServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package com.techcourse.service;

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

import com.techcourse.config.DataSourceConfig;
import com.techcourse.dao.UserDao;
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 com.techcourse.support.jdbc.init.ResourceNames;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

@Disabled
class UserServiceTest {
Expand All @@ -25,7 +26,7 @@ void setUp() {
this.jdbcTemplate = new JdbcTemplate(DataSourceConfig.getInstance());
this.userDao = new UserDao(jdbcTemplate);

DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance(), ResourceNames.SCHEMA_RESOURCE_NAME);
final var user = new User("gugu", "password", "[email protected]");
userDao.insert(user);
}
Expand Down
1 change: 1 addition & 0 deletions app/src/test/resources/truncate.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TRUNCATE TABLE USERS;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.springframework.dao;

public class IncorrectResultSizeException extends RuntimeException {

public IncorrectResultSizeException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.springframework.jdbc;

public class CannotCloseStatementException extends RuntimeException {

public CannotCloseStatementException(final String message) {
super(message);
}
}
Loading
Loading