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

[1단계 - JDBC 라이브러리 구현하기] 베베(최원용) 미션 제출합니다. #264

Merged
merged 10 commits into from
Sep 28, 2023
127 changes: 108 additions & 19 deletions app/src/main/java/com/techcourse/dao/UserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao {
Expand All @@ -27,27 +28,27 @@ public UserDao(final JdbcTemplate jdbcTemplate) {
}

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

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

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

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

Expand All @@ -60,25 +61,82 @@ public void insert(final User user) {
}

public void update(final User user) {
// todo
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
final String sql = "update users set account=?, password=?, email=? where id=?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, user.getAccount());
preparedStatement.setString(2, user.getPassword());
preparedStatement.setString(3, user.getEmail());
preparedStatement.setLong(4, user.getId());
preparedStatement.executeUpdate();
} catch (SQLException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException ignored) {}

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

public List<User> findAll() {
// todo
return null;
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
final String sql = "select * from users";
preparedStatement = connection.prepareStatement(sql);
final ResultSet resultSet = preparedStatement.executeQuery();

final List<User> users = new ArrayList<>();
while (resultSet.next()) {
final Long id = resultSet.getLong("id");
final String account = resultSet.getString("account");
final String password = resultSet.getString("password");
final String email = resultSet.getString("email");
users.add(new User(id, account, password, email));
}
return users;
} catch (SQLException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException ignored) {}

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

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

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

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

Expand All @@ -101,8 +159,8 @@ public User findById(final Long id) {
} catch (SQLException ignored) {}

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

Expand All @@ -115,7 +173,38 @@ public User findById(final Long id) {
}

public User findByAccount(final String account) {
// todo
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
final String sql = "select * from users where account = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, account);
final ResultSet resultSet = preparedStatement.executeQuery();

while (resultSet.next()) {
final Long id = resultSet.getLong("id");
final String password = resultSet.getString("password");
final String email = resultSet.getString("email");
return new User(id, account, password, email);
}
} catch (SQLException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException ignored) {}

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
Expand All @@ -19,9 +20,10 @@ public static void execute(final DataSource dataSource) {
Connection connection = null;
Statement statement = null;
try {
final var url = DatabasePopulatorUtils.class.getClassLoader().getResource("schema.sql");
final var file = new File(url.getFile());
final var sql = Files.readString(file.toPath());
final URL url = DatabasePopulatorUtils.class.getClassLoader().getResource("schema.sql");
final File file = new File(url.getFile());
final String sql = Files.readString(file.toPath());

connection = dataSource.getConnection();
statement = connection.createStatement();
statement.execute(sql);
Expand Down
4 changes: 3 additions & 1 deletion app/src/test/java/com/techcourse/dao/UserDaoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.sql.SQLException;

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

class UserDaoTest {
Expand All @@ -17,7 +19,7 @@ void setup() {
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance());

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

Expand Down
15 changes: 15 additions & 0 deletions study/src/test/java/connectionpool/stage1/Stage1Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,31 @@ class Stage1Test {
* Connection Pooling and Statement Pooling
* https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/javax/sql/package-summary.html
*/

// 여기서 드는 의문
// 미리 만들어둔 커넥션은 재사용이 가능하니,
// 미리 만들지 않았을 때는 초기 연결만 느리고,
// 데이터베이스 최대 커넥션만큼 다 만들어 졌을 때는
// 미리 커넥션을 만들어 둔 것과 비교해서 차이가 있는가?
// (나는 없을 것 같다고 생각한다.)
@Test
wonyongChoi05 marked this conversation as resolved.
Show resolved Hide resolved
void testJdbcConnectionPool() throws SQLException {
final JdbcConnectionPool jdbcConnectionPool = JdbcConnectionPool.create(H2_URL, USER, PASSWORD);

// 커넥션이 미리 만들어져 있지 않음을 검증한다.
assertThat(jdbcConnectionPool.getActiveConnections()).isZero();

// 커넥션 풀에서 커넥션을 꺼내온다.
try (final var connection = jdbcConnectionPool.getConnection()) {
// 꺼내온 커넥션이 유효한 커넥션인가?
assertThat(connection.isValid(1)).isTrue();
// 꺼내온 커넥션이 활성 상태인가?
assertThat(jdbcConnectionPool.getActiveConnections()).isEqualTo(1);
}
// 커넥션 풀에 활성 상태인 커넥션이 없는가?
assertThat(jdbcConnectionPool.getActiveConnections()).isZero();

// 커넥션 풀 닫기
jdbcConnectionPool.dispose();
}

Expand Down Expand Up @@ -65,6 +79,7 @@ void testHikariCP() {
hikariConfig.setUsername(USER);
hikariConfig.setPassword(PASSWORD);
hikariConfig.setMaximumPoolSize(5);

hikariConfig.addDataSourceProperty("cachePrepStmts", "true");
hikariConfig.addDataSourceProperty("prepStmtCacheSize", "250");
hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
Expand Down
3 changes: 3 additions & 0 deletions study/src/test/java/connectionpool/stage2/Stage2Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ void test() throws InterruptedException {
}

// 동시에 많은 요청이 몰려도 최대 풀 사이즈를 유지한다.
System.out.println("hikariPool.getTotalConnections() = " + hikariPool.getTotalConnections());
System.out.println("DataSourceConfig.MAXIMUM_POOL_SIZE = " + DataSourceConfig.MAXIMUM_POOL_SIZE);
assertThat(hikariPool.getTotalConnections()).isEqualTo(DataSourceConfig.MAXIMUM_POOL_SIZE);

// DataSourceConfig 클래스에서 직접 생성한 커넥션 풀.
System.out.println("hikariDataSource.getPoolName() = " + hikariDataSource.getPoolName());
assertThat(hikariDataSource.getPoolName()).isEqualTo("gugu");
}

Expand Down
Binary file added study/test.mv.db
Binary file not shown.
Loading