-
Notifications
You must be signed in to change notification settings - Fork 300
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단계] 에단(김석호) 미션 제출합니다. #321
Changes from all commits
dc70d1d
7182a49
06379e5
b5cbe34
0715ef4
7d7ef8a
175cc19
ed25724
be02dc7
21e50b8
4436f42
fbd58eb
7a759f3
af425e8
ba562ea
6f21f47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
name: SonarCloud | ||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
jobs: | ||
build: | ||
name: Build and analyze | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis | ||
- name: Set up JDK 11 | ||
uses: actions/setup-java@v3 | ||
with: | ||
java-version: 11 | ||
distribution: 'corretto' # Alternative distribution options are available | ||
- name: Cache SonarCloud packages | ||
uses: actions/cache@v3 | ||
with: | ||
path: ~/.sonar/cache | ||
key: ${{ runner.os }}-sonar | ||
restore-keys: ${{ runner.os }}-sonar | ||
- name: Cache Gradle packages | ||
uses: actions/cache@v3 | ||
with: | ||
path: ~/.gradle/caches | ||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} | ||
restore-keys: ${{ runner.os }}-gradle | ||
- name: Build and analyze | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any | ||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
run: ./gradlew clean build codeCoverageReport sonar --info -x :study:build |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -171,3 +171,5 @@ Temporary Items | |
|
||
tomcat.* | ||
tomcat.*/** | ||
|
||
**/WEB-INF/classes/** |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,9 @@ | ||
# JDBC 라이브러리 구현하기 | ||
|
||
## 기능 구현 목록 | ||
- [x] UserDaoTest 성공하게 만들기 | ||
- [x] findAll() | ||
- [x] findByAccount() | ||
- [x] findById() | ||
- [x] update() | ||
- [x] JdbcTemplate 으로 중복 제거 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,52 @@ | ||
package com.techcourse.dao; | ||
|
||
import com.techcourse.domain.User; | ||
import nextstep.jdbc.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 org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.jdbc.core.RowMapper; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public class UserDao { | ||
|
||
private static final Logger log = LoggerFactory.getLogger(UserDao.class); | ||
|
||
private final DataSource dataSource; | ||
private static final RowMapper<User> USER_ROW_MAPPER = resultSet -> new User(resultSet.getLong("id"), | ||
resultSet.getString("account"), | ||
resultSet.getString("password"), | ||
resultSet.getString("email")); | ||
|
||
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, user.getAccount(), user.getPassword(), user.getEmail()); | ||
} | ||
|
||
public void update(final User user) { | ||
// todo | ||
final var sql = "update users set (account, password, email) = (?, ?, ?) where id = ?"; | ||
|
||
jdbcTemplate.execute(sql, user.getAccount(), user.getPassword(), user.getEmail(), user.getId()); | ||
} | ||
|
||
public List<User> findAll() { | ||
// todo | ||
return null; | ||
final var sql = "select id, account, password, email from users"; | ||
|
||
return jdbcTemplate.query(sql, USER_ROW_MAPPER); | ||
} | ||
|
||
public User findById(final Long id) { | ||
public Optional<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, USER_ROW_MAPPER, id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 메서드에서 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dao는 DB에서 데이터를 찾아오는 역할만 하는게 좋다고 생각해요. 데이터가 찾을 때 문제가 생기면 dao에서 예외처리를 해도 되지만, 데이터의 존재 유무는 Service 영역에서 처리하게는게 책임에 맞다고 생각합니다~ |
||
} | ||
|
||
public User findByAccount(final String account) { | ||
// todo | ||
return null; | ||
public Optional<User> findByAccount(final String account) { | ||
final var sql = "select id, account, password, email from users where account = ?"; | ||
|
||
return jdbcTemplate.queryForObject(sql, USER_ROW_MAPPER, account); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 질문인데요!
DataSource를 받는 생성자는 왜 지우신건가요? ㅎㅎ
이런 식으로 활용도 가능했을 것 같은데 지우신 이유가 궁금합니당 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataSource를 주입받는건 dataSource가 변경될 여지가 있다는 생각하에 dataSource를 주입한다고 생각해요. 그런데 dataSource가 바뀌면 그에 따라서 jdbcTemplate 구현이 달라질거 같아서 새로운 jdbcTemplate으로 주입받는게 낫지 않을까? 하는 생각으로 바꿔놨습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Datasource가 바뀌면 jdbcTemplate의 구현이 달라질 것 같다는 말씀에 조금 헷갈리는 점이 있어서 여쭤봅니당!
Datasource는 인터페이스인데,어떤 부분이 jdbcTemplate의 구현에 영향을 미칠 수 있나요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제가 뭔가 착각하고 있었나봐요🥲 mysql에서 oracle로 바뀌면 문법이 바뀌니까 jdbcTemplate도 바뀌지 않을까라는 생각을 했었네요. sql은 정작 parameter로 받는데 말이죠. 저의 잘못된 뇌피셜이었습니다.
추가로 다른 이유를 붙이자면 dao에서 직접 jdbctemplate을 사용하면 jdbcTemplate이 bean일 때 새로운 객체를 안만들어도 되겠네요. 내부구현이 안바뀌니깐요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇군요 ㅎㅎ 에단 덕분에 많이 배울 수 있었습니다. 감사합니다 👍👍👍