Skip to content

Commit

Permalink
[JDBC 라이브러리 구현하기 - 1단계] 에밀(김대희) 미션 제출합니다. (#293)
Browse files Browse the repository at this point in the history
* 패키지 위치 변경 및 코드 정리

* feat: UserDao 구현

* refactor: insret, update 문 중복 제거

* refactor: 중복 로직 jdbctemplate으로 전부 이동

---------

Co-authored-by: kang-hyungu <[email protected]>
  • Loading branch information
CFalws and kang-hyungu authored Oct 2, 2023
1 parent 7182a49 commit e578e69
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 92 deletions.
129 changes: 38 additions & 91 deletions app/src/main/java/com/techcourse/dao/UserDao.java
Original file line number Diff line number Diff line change
@@ -1,121 +1,68 @@
package com.techcourse.dao;

import com.techcourse.domain.User;
import org.springframework.jdbc.core.JdbcTemplate;
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;

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;

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 (?, ?, ?)";

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.execute(sql, ps -> {
ps.setString(1, user.getAccount());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
});
}

public void update(final User user) {
// todo
final var sql = "update users set account = ?, password = ?, email = ? where id = ?";

jdbcTemplate.execute(sql, ps -> {
ps.setString(1, user.getAccount());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
ps.setLong(4, user.getId());
});
}

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

return jdbcTemplate.queryAll(sql, rs -> new User(
rs.getLong(1),
rs.getString(2),
rs.getString(3),
rs.getString(4)
));
}

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.query(sql, rs -> new User(
rs.getLong(1),
rs.getString(2),
rs.getString(3),
rs.getString(4)
), id);
}

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

return jdbcTemplate.query(sql, rs -> new User(
rs.getLong(1),
rs.getString(2),
rs.getString(3),
rs.getString(4)
), account);
}
}
3 changes: 2 additions & 1 deletion app/src/test/java/com/techcourse/dao/UserDaoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.techcourse.support.jdbc.init.DatabasePopulatorUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;

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

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

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 Down
124 changes: 124 additions & 0 deletions jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package org.springframework.jdbc.core;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;

public class JdbcTemplate {

Expand All @@ -14,4 +21,121 @@ public class JdbcTemplate {
public JdbcTemplate(final DataSource dataSource) {
this.dataSource = dataSource;
}


public DataSource getDataSource() {
return dataSource;
}

public void execute(String sql, MyPreparedStatementCallback myPreparedStatementCallback) {
Connection conn = null;
PreparedStatement pstmt = null;

try {
conn = dataSource.getConnection();

log.info("query: {}", sql);
pstmt = conn.prepareStatement(sql);

myPreparedStatementCallback.execute(pstmt);
pstmt.executeUpdate();
} catch (SQLException e) {
throw new DataAccessException(e);
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException ignored) {}

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

public <T> List<T> queryAll(String sql, ObjectMapper<T> objectMapper, Object... params) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();

log.info("query: {}", sql);
pstmt = conn.prepareStatement(sql);
for (int i = 1; i <= params.length; i++) {
pstmt.setObject(i, params[i - 1]);
}
rs = pstmt.executeQuery();

List<T> list = new ArrayList<>();
while (rs.next()) {
list.add(objectMapper.map(rs));
}
return list;
} catch (SQLException e) {
throw new DataAccessException(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) {}
}
}

public <T> T query(String sql, ObjectMapper<T> objectMapper, Object... params) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();

log.info("query: {}", sql);
pstmt = conn.prepareStatement(sql);
for (int i = 1; i <= params.length; i++) {
pstmt.setObject(i, params[i - 1]);
}
rs = pstmt.executeQuery();

if (rs.next()) {
return objectMapper.map(rs);
}
return null;
} catch (SQLException e) {
throw new DataAccessException(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) {}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.springframework.jdbc.core;

import java.sql.PreparedStatement;
import java.sql.SQLException;

@FunctionalInterface
public interface MyPreparedStatementCallback {

void execute(PreparedStatement pstmt) throws SQLException;

}
10 changes: 10 additions & 0 deletions jdbc/src/main/java/org/springframework/jdbc/core/ObjectMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.springframework.jdbc.core;

import java.sql.ResultSet;
import java.sql.SQLException;

@FunctionalInterface
public interface ObjectMapper<T> {

T map(ResultSet rs) throws SQLException;
}
1 change: 1 addition & 0 deletions study/src/main/java/aop/config/DataSourceConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class DataSourceConfig {
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.setName("test;DB_CLOSE_DELAY=-1;MODE=MYSQL;")
.addScript("classpath:schema.sql")
.build();
}
Expand Down
1 change: 1 addition & 0 deletions study/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
spring:
jpa:
open-in-view: false
show-sql: true
generate-ddl: true
hibernate:
Expand Down

0 comments on commit e578e69

Please sign in to comment.