mysql-connector-java 필요
try (
var connection = DriverManager.getConnection(URL, USER, PASSWORD);
var statement = connection.prepareStatement(SELECT_ALL_SQL);
var resultSet = statement.executeQuery();
) {
...
} catch (SQLException e) {
logger.error("Got error while closing connection", e);
}
try-with-resources
try-with-resources
를 사용하면 일일히 connection을 닫을 필요가 없다. try 블록을 닫으면 connection, statement, resultSet에 대해 알아서 close가 호출된다.var SELECT_SQL = "select * from customers where name = '" + name +"'";
문자열을 이용한 query는 SQL injection에 취약하다. 즉 query로 인해 의도하지 않은 조회 및 수정이 일어날 수 있다. 이러한 문제를 해결하기 위해 prepared statement를 사용해야 한다.
private final String PREPARE_SELECT_SQL = "select * from customers where name = ?";
try (
var connection = DriverManager.getConnection(URL, USER, PASSWORD);"root1234!");
var statement = connection.prepareStatement(INSERT_SQL);
) {
statement.setBytes(1, customerId.toString().getBytes());
statement.setString(2, name);
statement.setString(3, email);
return statement.executeUpdate();
} catch (SQLException e) {
logger.error("Got error while closing connection", e);
}
입력 인덱스는 1부터 시작한다.
try (
var connection = DriverManager.getConnection(URL, USER, PASSWORD);
var statement = connection.prepareStatement(PREPARE_SELECT_SQL);
) {
statement.setString(1, name);
try(var resultSet = statement.executeQuery()) {
while(resultSet.next()) {
var customerName = resultSet.getString("name");
var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
var createdAt = resultSet.getTimestamp("created_at").toLocalDateTime();
logger.info("customer id -> {}, name -> {}, createdAt -> {}", customerId, customerName, createdAt);
}
}
} catch (SQLException e) {
logger.error("Got error while closing connection", e);
}
시간은 LocalDatetime을 사용하자. 다만 resultSet.getTimestamp("created_at")에서 NULL이 나올 수도 있으니 조심하자!
try (
var connection = DriverManager.getConnection(URL, USER, PASSWORD);
var statement = connection.prepareStatement(UPDATE_NAME_BY_ID_SQL);
) {
statement.setString(1, name);
statement.setBytes(2, customerId.toString().getBytes());
return statement.executeUpdate();
} catch (SQLException e) {
logger.error("Got error while closing connection", e);
}
try (
var connection = DriverManager.getConnection(URL, USER, PASSWORD);
var statement = connection.prepareStatement(DELETE_ALL);
) {
return statement.executeUpdate();
} catch (SQLException e) {
logger.error("Got error while closing connection", e);
}
입력된 UUID와 조회된 UUID가 일치하지 않는 문제가 발생하였다.
이유
UUID 생성 버전이 달라서 발생한 문제이다.
nameUUIDFromByte
type 3
randomUUID
type 4
해결
var customerId = UUID.randomUUID();
var customerId = toUUID(resultSet.getBytes("customer_id"));
...
static UUID toUUID(byte[] bytes) {
var byteBuffer = ByteBuffer.wrap(bytes);
return new UUID(byteBuffer.getLong(), byteBuffer.getLong());
}