반응형
JDBC와 함께 try-with-resources를 어떻게 사용해야합니까?
JDBC를 사용하여 데이터베이스에서 사용자를 가져 오는 방법이 있습니다.
public List<User> getUser(int userId) {
String sql = "SELECT id, name FROM users WHERE id = ?";
List<User> users = new ArrayList<User>();
try {
Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, userId);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
이 코드를 개선하기 위해 Java 7 try-with-resources 를 어떻게 사용해야 합니까?
아래 코드로 시도했지만 많은 try
블록을 사용 하고 가독성을 크게 향상시키지 않습니다 . try-with-resources
다른 방법으로 사용해야 합니까?
public List<User> getUser(int userId) {
String sql = "SELECT id, name FROM users WHERE id = ?";
List<User> users = new ArrayList<>();
try {
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql);) {
ps.setInt(1, userId);
try (ResultSet rs = ps.executeQuery();) {
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
나는 이것이 오래전에 응답했지만 중첩 된 리소스를 사용하는 이중 블록을 피하는 추가 접근법을 제안하고 싶습니다.
public List<User> getUser(int userId) {
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = createPreparedStatement(con, userId);
ResultSet rs = ps.executeQuery()) {
// process the resultset here, all resources will be cleaned up
} catch (SQLException e) {
e.printStackTrace();
}
}
private PreparedStatement createPreparedStatement(Connection con, int userId) throws SQLException {
String sql = "SELECT id, username FROM users WHERE id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, userId);
return ps;
}
예제에서 외부 시도가 필요하지 않으므로 적어도 3에서 2로 내려갈 수 ;
있으며 리소스 목록의 끝에서 닫을 필요가 없습니다 . 두 개의 try 블록을 사용하면 모든 코드가 미리 표시되므로 별도의 방법을 참조 할 필요가 없습니다.
public List<User> getUser(int userId) {
String sql = "SELECT id, username FROM users WHERE id = ?";
List<User> users = new ArrayList<>();
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql)) {
ps.setInt(1, userId);
try (ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
Here is a concise way using lambdas and JDK 8 Supplier to fit everything in the outer try:
try (Connection con = DriverManager.getConnection(JDBC_URL, prop);
PreparedStatement stmt = ((Supplier<PreparedStatement>)() -> {
try {
PreparedStatement s = con.prepareStatement(
"SELECT userid, name, features FROM users WHERE userid = ?");
s.setInt(1, userid);
return s;
} catch (SQLException e) { throw new RuntimeException(e); }
}).get();
ResultSet resultSet = stmt.executeQuery()) {
}
What about creating an additional wrapper class?
package com.naveen.research.sql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public abstract class PreparedStatementWrapper implements AutoCloseable {
protected PreparedStatement stat;
public PreparedStatementWrapper(Connection con, String query, Object ... params) throws SQLException {
this.stat = con.prepareStatement(query);
this.prepareStatement(params);
}
protected abstract void prepareStatement(Object ... params) throws SQLException;
public ResultSet executeQuery() throws SQLException {
return this.stat.executeQuery();
}
public int executeUpdate() throws SQLException {
return this.stat.executeUpdate();
}
@Override
public void close() {
try {
this.stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Then in the calling class you can implement prepareStatement method as:
try (Connection con = DriverManager.getConnection(JDBC_URL, prop);
PreparedStatementWrapper stat = new PreparedStatementWrapper(con, query,
new Object[] { 123L, "TEST" }) {
@Override
protected void prepareStatement(Object... params) throws SQLException {
stat.setLong(1, Long.class.cast(params[0]));
stat.setString(2, String.valueOf(params[1]));
}
};
ResultSet rs = stat.executeQuery();) {
while (rs.next())
System.out.println(String.format("%s, %s", rs.getString(2), rs.getString(1)));
} catch (SQLException e) {
e.printStackTrace();
}
참고URL : https://stackoverflow.com/questions/8066501/how-should-i-use-try-with-resources-with-jdbc
반응형
'Programing' 카테고리의 다른 글
그룹 객체에 변형 대 적용 (0) | 2020.06.25 |
---|---|
Django TemplateDoesNotExist? (0) | 2020.06.25 |
Bash를 사용하여 마지막 명령의 출력을 변수로 자동 캡처합니까? (0) | 2020.06.25 |
실제로 오버로드 된 && 및 || 이유가 있습니까? (0) | 2020.06.25 |
이 방법으로 숫자의 제곱을 계산할 수 없습니다 (0) | 2020.06.25 |