JDBC 的代码简化
很多JDBC的教程和博文还在用较旧的方式来访问数据库。
利用 Java 6 的 JDBC 4.0 API
和 Java 7 的 try-with-resources
语法可以大大简化冗长的代码。
Java 7 以前的写法
可以看到有很多资源清理的操作,也要手动装载 JDBC 驱动
private static final String URL = "jdbc:mysql://localhost";
private static final String USER = "root";
private static final String PASSWD = "secret";
private static final String STATEMENT = "SHOW DATABASES";
public static void priorJava7JDBC() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver"); // 注册驱动
conn = DriverManager.getConnection(URL, USER, PASSWD); // 打开连接
stmt = conn.createStatement();
rs = stmt.executeQuery(STATEMENT); // 执行语句
// 处理结果
while (rs.next()) {
System.out.println(rs.getString("Database"));
}
// 资源清理
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeQuietly(rs);
closeQuietly(stmt);
closeQuietly(conn);
}
}
public static void closeQuietly(AutoCloseable closeable) {
try {
if(closeable != null) {
closeable.close();
}
} catch (Exception e) {
}
}
Java 7 之后的写法
通过try-with-resources
省略了资源清理的代码,类似与 Python 的 with
语法,也无需注册驱动
public static void afterJava7JDBC() {
try (Connection connection = DriverManager.getConnection(URL, USER, PASSWD);
PreparedStatement stmt = connection.prepareStatement(STATEMENT)) {
try (ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
System.out.println(rs.getString("Database"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
try-with-resources 异常处理方式
try-with-resources 可以理解为自动调用 close 方法的语法糖,但异常处理有差异,看下面的例子
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
readFirstLineFromFileWithFinallyBlock方法如果 readLine 和 close 同时抛出异常,方法的异常会是 finally 语句块的异常。try 语句块的异常被suppressed。 相比之下,readFirstLineFromFile方法如果 readLine 和 try-with-resources 调 close 方法都抛出异常,方法的异常会是 try 语句块的异常,即 readLine 的异常, try-with-resources 的异常被suppressed。可以通过抛出的异常调用 Throwable.getSuppressed 方法获得 try-with-resources 的异常。
原文描述如下:
However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the method readFirstLineFromFile throws the exception thrown from the try block; the exception thrown from the try-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the section Suppressed Exceptions for more information.
还可以更简便吗
上面的代码虽然有一定程度简化,但还是需要打开连接、执行语句、遍历结果集等操作,
通过 Spring 的 JdbcTemplate
配合 Java 8 的流式api以及lambda表达式可以让代码变得更加简洁,接近One-Liners。例如:
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?", new Object[] { "Josh" },
(rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name"))
).forEach(customer -> log.info(customer.toString()));
具体可看教程