欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringInAction第十章学习笔记:Spring 和JDBC

程序员文章站 2024-02-16 10:45:58
...

10.1 Spring的数据访问哲学

为了避免应用与特定的数据访问策略耦合在一起, 编写良好的Repository应该以接口的方式暴露功能。

10.1.1 了解Spring的数据访问异常体系

原始的JDBC强制捕获SQLException,SQLException表示在尝试访问数据库的时出现了问题。可能导致抛出SQLException的常见问题包括:应用程序无法连接数据库;要执行的查询存在语法错误;查询中所使用的表和/或列不存在;试图插入或更新的数据违反了数据库约束通常catch到SQLException后也无法进行异常处理。对于所有的数据访问问题都会抛出SQLException。不同于JDBC, Spring提供了多个数据访问异常。但这些异常都继承自DataAccessException。是一个非检查型异常。

10.1.2 数据访问模板化

模板方法将过程中与特定实现相关的部分委托给接口,而这个接口的不同实现定义了过程中的具体行为。Spring将数据访问过程中固定的和可变的部分明确划分为两个不同的类: 模板(template) 和回调(callback)。Spring的模板类处理数据访问的固定部分——事务控制、 管理资源以及处理异常。同时,应用程序相关的数据访问——语句、绑定参数以及整理结果集——在回调的实现中处理。针对不同的持久化平台, Spring提供了多个可选的模板:
SpringInAction第十章学习笔记:Spring 和JDBC

在声明模板和Repository之前, 我们需要在Spring中配置一个数据源用来连接数据库。

10.2 配置数据源

Spring提供了在Spring上下文中配置数据源bean的多种方式, 包括:

  1. 通过JDBC驱动程序定义的数据源;

  2. 通过JNDI查找的数据源;

  3. 连接池的数据源。

10.2.1 使用JNDI数据源

JNDI数据源配置的好处在于数据源完全可以在应用程序之外进行管理, 这样应用程序只需在访问数据库的时候查找数据源。在应用服务器中管理的数据源通常以池的方式组织, 从而具备更好的性能, 并且还支持系统管理员对其进行热切换。
利用Spring, 我们可以像使用Spring bean那样配置JNDI中数据源的引用并将其装配到需要的类中。 位于jee命名空间下的jee:jndi-lookup元素可以用于检索JNDI中的任何对象(包括数据源) 并将其作为Spring的bean。例如,如果应用程序的数据源配置在JNDI中, 我们可以使用jee:jndi-lookup元素将其装配到Spring中,如下所示:

  1. 先要先在Tomcat中进行JNDI源的配置,在Tomcat/Conf/context.xml中配置如下:
    SpringInAction第十章学习笔记:Spring 和JDBC
  2. 在数据源配置中,使用位于jee命名空间下的jee:jndi-lookup元素可以用于检索JNDI中的任何对象(包括数据源) 并将其作为Spring的bean。其中jndi-name属性用于指定JNDI中资源的名称。 如果只设置了jndi-name属性, 那么就会根据指定的名称查找数据源。 但是, 如果应用程序运行在Java应用服务器中, 你需要将resource-ref属性设置为true, 这样给定的jndi-name将会自动添加“java:comp/env/”前缀。如下,原本是通过db.prop配置进行数据源配置的读取,现使用JDNI配置后用jee标签读取到dataSource,使用测试成功访问到数据库。注意,上面的配置中配置了DBCP连接池,如果项目中没有依赖必须删掉。
    .SpringInAction第十章学习笔记:Spring 和JDBC
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/mmcDB"/>

相当于

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/mmcDB" resource-ref="true"/> 

使用resource-ref属性会自动添加“java:comp/env/”前缀。
使用java配置如下,同时也需要在java配置中进行mybatis等等的配置:

SpringInAction第十章学习笔记:Spring 和JDBC

10.2.2使用数据源连接池

Spring没有提供数据源连接池实现,但有包括如下开源的实现:
Apache Commons DBCP (http://jakarta.apache.org/commons/dbcp);
c3p0 (http://sourceforge.net/projects/c3p0/) ;
BoneCP (http://jolbox.com/)

添加C3P0依赖:

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

SpringInAction第十章学习笔记:Spring 和JDBC
SpringInAction第十章学习笔记:Spring 和JDBC
前四个属性是配置BasicDataSource所必需的。 属性driverClassName指定了JDBC驱动类的全限定类名。属性url用于设置数据库的JDBC URL。 最后, username和password用于在连接数据库时进行认证。

10.2.3 基于JDBC驱动的数据源

在Spring中, 通过JDBC驱动定义数据源是最简单的配置方式。 Spring提供了三个这样的数据源类(均位于org.springframework.jdbc.datasource包中) 供选择:

  • DriverManagerDataSource: 在每个连接请求时都会返回一个新建的连接。 与DBCP的BasicDataSource不同, 由DriverManagerDataSource提供的连接并没有进行池化管理;
  • SimpleDriverDataSource: 与DriverManagerDataSource的工作方式类似, 但是它直接使用JDBC驱动, 来解决在特定环境下的类加载问题, 这样的环境包括OSGi容器;
  • SingleConnectionDataSource: 在每个连接请求时都会返回同一个的连接。可以将其视为只有一个连接的池。
    SpringInAction第十章学习笔记:Spring 和JDBC

10.2.4 使用嵌入式的数据源

嵌入式数据库(embedded database)作为应用的一部分运行, 而不是应用连接的独立数据库服务器。对于开发和测试来讲,每次重启应用或运行测试的时候, 都能够重新填充测试数据。
Spring的jdbc命名空间能够简化嵌入式数据库的配置。

SpringInAction第十章学习笔记:Spring 和JDBC
SpringInAction第十章学习笔记:Spring 和JDBC
Schema.sql里进行建表操作,test-data.sql里进行插入数据库操作。jdbc:embedded-database元素还会暴露一个数据源,我们可以像使用其他的数据源那样来使用它。在这里, id属性被设置成了dataSource。如果使用Java来配置嵌入式数据库时, 不会像jdbc命名空间那么简便, 我们可以使用EmbeddedDatabaseBuilder来构建DataSource。

10.2.5 使用profile选择数据源

如下,可设置两个profile进行数据源切换:
SpringInAction第十章学习笔记:Spring 和JDBC

10.3 在Spring中使用JDBC

使用JDBC能够更好地对数据访问的性能进行调优。JDBC允许使用数据库的所有特性。但大量的JDBC代码都是用于创建连接和语句以及异常处理的样板代码。Spring的JDBBC框架承担了资源管理和异常处理的工作,从而简化了JDBC代码。
Spring提供了3个模板类:

  • JdbcTemplate:最基本的SpringJDBC模板。支持简单的JDBC数据库访问功能以及基于索引参数的查询
  • NamedParameterJdbcTemplate:使用该模板类执行查询时可以将值以命名参数的形式绑定到SQL中。
  • SimpleJdbcTemplate:该模板类利用Java5的特性简化JDBC模板使用从Spring3.1开始,SimpleJdbcTemplate已废弃,需要用命名参数时使用NamedParameterJdbcTemplate 否则绝大多数都是使用JdbcTemplate。

使用JdbcTemplate,需要配置DataSource,如下即可:

SpringInAction第十章学习笔记:Spring 和JDBC
注入的DataSource可以由上面的配置生成Bean。生成操作类如下,例如此时对User表进行操作。

SpringInAction第十章学习笔记:Spring 和JDBC
JdbcOperations是一个接口,定义了JdbcTemplate所实现的操作。注入其接口可以保持松耦合(下次JdbcTemplate换了实现,这里可以不用换)
SpringInAction第十章学习笔记:Spring 和JDBC
当调用JdbTemplate方法时会获取连接,创建语句并执行SQL。实现RowMapper接口,对于返回的每一行数据,JdbcTemplate将会调用RowMapper的mapRow()方法,传入一个ResultSet和其行号。

使用命名参数:

SpringInAction第十章学习笔记:Spring 和JDBC

SpringInAction第十章学习笔记:Spring 和JDBC
在update方法中,使用命名参数方式进行参数传递。

相关标签: SpringInAction