Feb 21, 2017
很多JDBC的教程和博文还在用较旧的方式来访问数据库。
利用 Java 6 的JDBC 4.0 API
和 Java 7 的try-with-resources
语法可以大大简化冗长的代码。
可以看到有很多资源清理的操作,也要手动装载 JDBC 驱动
privatestaticfinalStringURL="jdbc:mysql://localhost";privatestaticfinalStringUSER="root";privatestaticfinalStringPASSWD="secret";privatestaticfinalStringSTATEMENT="SHOW DATABASES";publicstaticvoidpriorJava7JDBC(){Connectionconn=null;Statementstmt=null;ResultSetrs=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(Exceptione){e.printStackTrace();}finally{closeQuietly(rs);closeQuietly(stmt);closeQuietly(conn);}}publicstaticvoidcloseQuietly(AutoCloseablecloseable){try{if(closeable!=null){closeable.close();}}catch(Exceptione){}}
通过try-with-resources
省略了资源清理的代码,类似与 Python 的with
语法,也无需注册驱动
publicstaticvoidafterJava7JDBC(){try(Connectionconnection=DriverManager.getConnection(URL,USER,PASSWD);PreparedStatementstmt=connection.prepareStatement(STATEMENT)){try(ResultSetrs=stmt.executeQuery()){while(rs.next()){System.out.println(rs.getString("Database"));}}}catch(SQLExceptione){e.printStackTrace();}}
try-with-resources 可以理解为自动调用 close 方法的语法糖,但异常处理有差异,看下面的例子
staticStringreadFirstLineFromFileWithFinallyBlock(Stringpath)throwsIOException{BufferedReaderbr=newBufferedReader(newFileReader(path));try{returnbr.readLine();}finally{if(br!=null)br.close();}}staticStringreadFirstLineFromFile(Stringpath)throwsIOException{try(BufferedReaderbr=newBufferedReader(newFileReader(path))){returnbr.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 = ?",newObject[]{"Josh"},(rs,rowNum)->newCustomer(rs.getLong("id"),rs.getString("first_name"),rs.getString("last_name"))).forEach(customer->log.info(customer.toString()));
具体可看教程