写点什么

Spring Boot「18」使用 JDBC 连接数据库

作者:Samson
  • 2022-10-31
    上海
  • 本文字数:2556 字

    阅读完需:约 8 分钟

01-Java JDBC

JDBC (Java Database Connectivity)是一组 API,它定义了 Java 进程连接数据库并执行 SQL 的接口。JDBC 是基于数据库驱动的接口封装。数据库驱动可以分为如下四种类型:


  • 第一种,将数据库访问映射到其他的数据库访问 API 上,其中最典型的就是 JDBC-ODBC 驱动;

  • 第二种,基于目标数据库的 client-api 实现,也被称为是 native-API 驱动;

  • 第三种,通过中间件,将对 JDBC 的调用转换为特定数据库的调用,也被称为是网络协议驱动;

  • 第四种,直接将对 JDBC 的调用转换为特定数据库的调用,也被称为是数据库协议驱动或 thin 驱动。注:最常用,性能较好,但针对每种数据库都需要有特定实现;mysql-connector-java 就是此类型实现。


使用 JDBC 访问数据库的步骤:


  1. 注册驱动。DriverManager 是 JDK 中java.sql包提供的 JDBC 驱动管理器。有两种方式可以向管理器中注册驱动:

  2. JDBC 4.0 / java se 6 之前,通过Class.forName("oracle.jdbc.driver.OracleDriver");,可以借助反射,将驱动类加载到 JVM 中。或者,也可以在运行 Java 程序时,通过参数jdbc.drivers指定要加载的驱动名称,例如:java -Djdbc.drivers=oracle.jdbc.driver.OracleDriver

  3. JDBC 4.0 / java se 6 开始,JDK 提供了 SPI 机制。它可以自动的加载 classpath 下 META-INF/service 目录中名为java.sql.Driver的文件,并自动将文件中指定的类加载到 JVM 中。

  4. 创建连接。将驱动注册到 DriverManger 之后,便可通过其 getConnection 方法获得数据库链接。创建链接时,一般需要指定如下的参数:

  5. url

  6. user

  7. password

  8. 其他跟特定数据库相关的配置

  9. 执行 SQL。创建链接之后,会获得一个 Connection 对象。通过这个连接对象,可以创建如下执行 SQL 的对象:

  10. Statement,connection.createStatement()。拿到 Statement 对象后,可以通过以下方式执行 SQL 语句:

  11. executeQuery 执行查询

  12. executeUpdate 执行更新

  13. execute 是上述两种方式的合集

  14. PreparedStatement,connection.prepareStatement()。与 Statement 类似,增加了对参数的支持。

  15. CallableStatement,connection.prepareCall。CallableStatement 主要用来调用存储过程。

  16. 解析执行结果

  17. ResultSet,通过rs.next()判断是否存在剩余未遍历的记录,通过 getX 可以获取每条记录中的属性,其中 X 表示类型,例如 String、Byte 等;

  18. 可更新的 ResultSet。默认情况下 ResultSet 结果是只读的。如果需要更新,在创建 Statement 时需要额外的参数。stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);。更多信息参考1

  19. 关闭资源。上述 3 和 4 步骤中的对象,使用完毕后需要释放。可以通过 try-catch-with-resources 减少关闭资源的样板代码。


除了上述标准的 SQL 查询、更新操作外,Connection 对象提供了查看与目标数据库连接的元数据接口,例如:DatabaseMetaData connMeta = connection.getMetaData();与 Connection 一样,ResultSet 也同样提供了查询结果相关的元数据接口,例如:ResultSetMetaData rsMeta = rs.getMetaData();

02-Spring JDBC

上节中介绍的是 JDK 中提供的 JDBC 接口。Spring 在其基础上提供了 Spring JDBC 封装,主要目的是使 JDBC 的使用更便捷,并且屏蔽底层烦琐的细节。


在 Spring JDBC 中,配置数据库连接,主要通过配置 DataSource 对象来实现。根据使用得数据库不同、或者使用的数据库连接池不同,DataSource 的类型也不尽相同。例如,Spring Boot 2 默认使用的是 HikariDataSource。在使用内存数据库时,例如 H2,Spring Boot 或 Spring JDBC 提供了数据库初始化的方式:


  • Spring Boot 在使用内存数据库时,其 autoconfigure 机制会加载 classpath 下的 schema.sql 和 data.sql 这两个脚本,主要在 SqlDataSourceScriptDatabaseInitializer 中实现。

  • Spring JDBC 中也提供了类似的实现,在使用内存数据库时,可以通过 EmbeddedDatabaseBuilder 加载初始化脚本,例如


@Beanpublic DataSource dataSource() {    return new EmbeddedDatabaseBuilder()    .setType(EmbeddedDatabaseType.H2)    .addScript("classpath:jdbc/schema.sql")    .addScript("classpath:jdbc/data.sql").build();}
复制代码


  • 如果使用 Hibernate,还会加载 classpath 下的 import.sql,并且可以通过 hibernate.hbm2ddl.import_files 指定要导入的文件路径。


Spring JDBC 中提供了 JdbcTemplate / NamedParameterJdbcTemplate 用来访问数据库进行查询、更新等操作,以及将查询结果转换为 Java object。JdbcTemplate 主要提供了以下接口用于执行 SQL 操作:


  • query、以及 queryForXXX,其中 XX 指 List、Map、Object、Stream 等,搭配 RowMapper 实现,方便将 ResultSet 直接转换为 Java object。

  • update、以及 batchUpdate 用于批量更新,后面章节中会详细介绍。

  • execute 执行 SQL 语句。

  • call 执行存储过程。


另外,Spring JDBC 还提供了 SimpleJdbc 类来简化 SQL 执行:


  • SimpleJdbcInsert

  • withTableName

  • usingGeneratedKeyColumns

  • SimpleJdbcCall

  • withProcedureName


除了上述这些功能,Spring JDBC 还提供了数据库错误码到标准 Spring 异常类 DataAccessException 及其子类的自动转换功能。默认使用 SQLErrorCodeSQLExceptionTranslator 作为异常转换器,如果有必要,可以通过继承来扩展其行为,开发自己的定制化转换器。例如:


public class MyDemoSQLErrorCodeTranslator extends SQLErrorCodeSQLExceptionTranslator { /**...*/ }
复制代码

03-批量处理

与数据库建立连接后,通过将 SQL 批量提交到数据库,可以减少通讯开销,提高整体的效率;或者,需要保证数据一致性,例如向多个表中插入数据,需要批量执行。批量处理是以上两种场景的应对方案之一。


如何批量执行 SQL 语句,JDBC 的 Statement 和 PreparedStatement 提供了 addBatch 和 executeBatch 搭配使用的方案。Spring JDBC 中的 JdbcTemplate 和 NamedParameterJdbcTemplate 提供了 batchUpdate 和 BatchPreparedStatementSetter 方案。


除了上述两种方案外,对支持批量语法的数据库,可以使用批量插入语句,例如 Postgres、MySQL、SQL。


--- MULTI-VALUE INSERTINSERT INTO COUNTRY(ID, NAME)VALUES(1, 'USA'),(2, 'France'),(3, 'Brazil'),(4, 'Italy');
复制代码

04-总结

今天我们一块学习了 JDK JDBC 和 Spring JDBC,以及如何进行批量处理。

发布于: 刚刚阅读数: 4
用户头像

Samson

关注

还未添加个人签名 2019-07-22 加入

InfoQ签约作者 | 阿里云社区签约作者

评论

发布
暂无评论
Spring Boot「18」使用 JDBC 连接数据库_Java_Samson_InfoQ写作社区