`
gao_xianglong
  • 浏览: 467779 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

笔者带你剖析Spring3.x JDBC

阅读更多

《笔者带你剖析Spring3.x JDBC》

 

前言

笔者在之前的系列博文中,曾经讲解过Apache旗下的DbUtils工具(http://gao-xianglong.iteye.com/blog/2166444)。简单来说,这一款工具对JDBC实施了非常轻量级的封装,只要你会使用JDBC,估计半个小时,或许你就能够熟练掌握DbUtils的基本用法,当然笔者并不是让你立即换掉你生产环境中的持久层选项,而是告诉你,在互联网场景下,越简单,越纯粹,越贴近原生是最好的,因为这样会拥有更好的灵活性、伸缩性,以及高性能(毕竟封装层次越高,开销越大,同样组件的“可见性”会更加模糊,对于开发人员而言,则为黑盒)。

 

无论从哪一个角度来看,DbUtils都是一款不错的持久层工具,天生具备优秀的灵活性、伸缩性,但是与此同时也伴随着一定的缺陷。试想一下,在一些项目周期较紧的情况下,你的Project Manager是不太可能给你足够充裕的时间去编写相应的Template(除非项目组编写有公共组件),并且在集成有Spring环境的项目中,也确实没有太多必要将DbUtils再次集成。看到这里,笔者本篇博文的主角诞生了,那就是Spring JDBC。同Apache的DbUtils相比,尽管Spring JDBC在封装上会显得更加“丰满”一些,但随之提升的简易性会大大缩短项目的开发周期,提高生产效率,因此所带来的一些额外开销也就不值一提。这便是笔者在当前项目中选择它的最主要的原因,有现成的Templet,以及同样不失灵活性、伸缩性的前提下,选择Spring JDBC作为持久层的开发工具将会比DbUtils更加诱人,那么说道这里,你,动心了吗?

 

目录

一、下载Spring JDBC的相关构件;

二、配置参数;

三、基于Spring JDBC的CRUD示例;

四、RowMapper;

五、JdbcTemplate;

六、基于@注解的声明式事物管理;

 

一、下载Spring JDBC的相关构件

 笔者使用Maven对项目进行管理,自然而言,就不会再单独进行Spring JDBC构件的下载,而是由Maven来对相关构件进行管理。在本篇博文中,笔者所使用的Spring版本为3.2.13,如下所示:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>${org.springframework-version}</version>
	<exclusions>
		<!-- Exclude Commons Logging in favor of SLF4j -->
		<exclusion>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-beans</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-orm</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jms</artifactId>
	<version>${org.springframework-version}</version>
</dependency>

 

二、配置参数

当Maven成功下载好Spring JDBC所需的构件后,接下来的任务就是在Spring持久层配置文件中配置相关的数据源信息。首先需要配置的是数据源信息,考虑到后期的维护性,数据源信息笔者单独存放在一个properties文件中,在Spring持久层配置文件中通过标签“<context:property-placeholder/>”进行加载。这里笔者插一句题外话,在一些大型的分布式+集群环境的项目中,最好采用集中式的资源配置方式,而非继续采用这种静态配置文件的方式,因为如果一旦配置信息发生改变时,可以动态响应,并通知程序实时更新,以此更大程度上降低维护成本,这里笔者推荐淘宝开源的Diamond中间件(实在不行,存放在DB也行,自己写个组件执行参数变化后的动态响应即可)。

 

回到正题,数据源信息无非就是定义了一堆与DB链接相关的参数以及连接池相关的信息,笔者在本篇博文中所使用的DB连接池为c3p0,当然你也可以选用其它的DB连接池,笔者在此不过多进行讲解。关于Spring JDBC的相关数据源配置参数,如下所示:

<!-- 加载本地数据源配置信息 -->
<context:property-placeholder location="classpath:*.properties" />
<!-- 定义数据源信息 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="user" value="${name}" />
	<property name="password" value="${password}" />
	<property name="jdbcUrl" value="${jdbcUrl}" />
	<property name="driverClass" value="${driverClass}" />
	<property name="initialPoolSize" value="${initialPoolSize}" />
	<property name="minPoolSize" value="${minPoolSize}" />
	<property name="maxPoolSize" value="${maxPoolSize}" />
	<property name="maxStatements" value="${maxStatements}" />
	<property name="maxIdleTime" value="${maxIdleTime}" />
</bean>
<!-- 配置JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="dataSource" />
</bean>

 

关于JdbcTemplet,笔者会在后续章节为大家进行详细的讲解,目前你只需要明白和了解,单纯配置数据源(不包括事物)是多么的简单即可。
 
三、基于Spring JDBC的CRUD示例
当大家成功配置好所需的配置信息后,接下来要做的事情就是编写一些简单的CRUD用例来进行测试,如下所示:
@Repository("userDao")
public class UserDaoImpl implements UserDao {
	@Resource
	private JdbcTemplate jdbcTemplate;

	@Resource
	private UserMapper userMapper;

	public List<User> queryUser() throws Exception {
		final String SQL = "SELECT u.* from user u";
		return jdbcTemplate.query(SQL, userMapper);
	}

	public User queryUserById() throws Exception {
		final String SQL = "SELECT u.* from user u where u.id = 1";
		return jdbcTemplate.queryForObject(SQL, userMapper);
	}

	public void insertUser(User user) throws Exception {
		final String SQL = "INSERT INTO user(id,name) VALUES(?,?)";
		jdbcTemplate.update(SQL, new Object[] { user.getId(), user.getName() });

	}

	public void updateUser(User user) throws Exception {
		final String SQL = "UPDATE user u set u.name = ? where u.id = ?";
		jdbcTemplate.update(SQL, new Object[] { user.getName(), user.getId() });
	}

	public void deleteUserbyId(int id) throws Exception {
		final String SQL = "DELETE FROM user where id = ?";
		jdbcTemplate.update(SQL, new Object[] { id });
	}
}
 
四、RowMapper
在上述程序示例中,大家可以看见笔者声明了一个成员变量UserMapper。简单来说,UserMapper实际上是一个与Entity对应的Mapper,对MyBatis有所了解的开发人员应该不会感到陌生。在Spring JDBC中,当我们进行数据检索时,如果希望Spring能够自动将结果集映射到Entity中所对应的字段上时,就需要首先编写一个与Entity对应的Mapper,这样Spring才知道,在检索结果集的时候执行值映射。
 
实现一个Mapper非常简单,首先需要实现一个全限定名为org.springframework.jdbc.core.RowMapper的接口,并重写其mapRow(ResultSet rs, int rowNum)方法。在此大家需要注意,在重写mapRow()方法时,参数rs实际上就是java.sql.ResultSet结果集,如果想实现结果集的映射,那么我们则需要手动在mapRow()方法中,将Entity中的参数一一进行set,而参数rs的用法,学过JDBC的开发人员都应该了解,笔者则不再过多进行讲解。关于Mapper的编写,如下所示:
@Component
public class UserMapper implements RowMapper<User> {
	public User mapRow(ResultSet rs, int rowNum) throws SQLException {
		User user = new User();
		user.setId(rs.getInt("id"));
		user.setName(rs.getString("name"));
		return user;
	}
}
 
五、JdbcTemplate
Template实际上就是一个封装后的CRUD模板。在Spring JDBC中,JdbcTemplate可以帮助开发人员实现大部分的CRUD操作,而不再需要像使用Dbutils那样,手动编写其对应的Template。简单来说,JdbcTemplate所提供的CURD方法可以分为2大类,一类是用于执行检索的query...()方法,而另外一类则是用于执行insert、update和delete的update()操作方法。
 
在JdbcTemplate中,执行数据检索有N多的方法都可以支持,如下所示:
 
其实更多时候,笔者最长使用的查询方法为query()和queryForObject(),而其它的比如检索单个字段的queryForInt()方法之流几乎不用,首先是这种类型的方法已经过时,其次使用query()方法完全已经可以满足绝大多数的场景。以query(String sql, RowMapper<T> rowMapper)方法为例,其参数为SQL语句和Mapper。如果希望SQL语句带有条件参数,那么则可以调用query(String sql, ResultSetExtractor<T> rse, Object... args)方法,参数由一个Object[]数组接收。
 
在此大家需要注意,对于初学者而言,使用queryForObject()进行数据检索时,如果查询出来的数据与预期不符,将会抛出org.springframework.dao.EmptyResultDataAccessException异常,比如我们期望查询出来的结果为1,而数据库并无数据,则会提示Incorrect result size: expected 1, actual 0。
 
六、基于@注解的声明式事物管理
事物管理其实是一个老生常谈的话题了,由Spring来执行事物管理是一件非常容易的事情。当然需要Spring管理我们的事物,首先要做的事情就是更改之前的配置文件,打开声明式事物即可,如下所示:
<!-- 定义事物注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 配置transactionManager -->
<bean id="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource">
		<ref local="dataSource" />
	</property>
</bean>
 
当在配置文件中定义好事物需要进行声明式管理后,我们还需要在Service层,添加@Transactional注解,该注解的作用域可以作用于类和方法。如果@Transactional添加在类上方,则意味着一个全局事务诞生,而添加在方法上时,则只会对当前方法产生事物。如果方法和类都有@Transactional注解时,则优先执行方法上的事物,如果方法没有标记事物,则执行全局事物。
 
一般来说,标记在类上方的都是只读事物,如下所示:
@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
 
而标记在类上方的才是真正需要开启事物,如下所示:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class, timeout = 20)
 
简单来说,propagation参数用于定义事物传播特性,Propagation.REQUIRED为如果当前方法没有事物,则新建一个事物,如果当前有事物,则归并为一个事物。isolation参数为事物隔离级别,一般来说,这个参数不要瞎弄,用default即可,毕竟要数据库支持才是可以。rollbackFor参数用于指定异常回滚,一旦程序中抛出运行时异常或者非运行时异常时,都将执行事物回滚,这里大家需要注意,千万不要手痒自己捕获异常,否则事物将不会进行回滚。timeout参数代表事物的执行时间,以秒为单位,如果事物在规定的时间内没有执行完毕,那么将执行事物回滚操作。
分享到:
评论

相关推荐

    spring 3.x企业应用开发实战

    文件中反复提及的“更多最新编程资源分享下载站***”并不是具体的Spring 3.x企业应用开发知识点。同时,重复的内容无法提供足够的信息来详细说明“Spring 3.x企业应用开发实战”中的知识点。 为了生成关于“Spring ...

    第一次搭建spring3.x需要的jar和搭建源码

    在搭建Spring 3.x开发环境时,我们首先要理解Spring的核心概念和它在Java应用程序中的作用。Spring是一个开源的Java框架,主要用于简化企业级应用的开发,通过依赖注入(Dependency Injection, DI)和面向切面编程...

    Spring3.x企业应用开发实战光盘源码

    《Spring3.x企业应用开发实战》是一本...通过分析和实践这些源码,读者可以深入理解Spring3.x框架的工作原理,掌握企业级应用开发的关键技能。同时,结合书中的理论知识,可以更好地将理论与实践相结合,提升开发能力。

    精通Spring4.x(包含源码)

    《精通Spring4.x》这本书是针对企业应用开发的深度指南,涵盖了Spring框架的核心技术,旨在帮助读者深入理解和熟练运用Spring4.x版本。书中的内容详细且实用,包括了以下几个主要的知识点: 1. **IoC(Inversion of...

    Spring 3.x 企业应用开发实战-源代码

    《Spring 3.x 企业应用开发实战》是一本深度探讨Spring框架在企业级应用中的实践指南,特别适合那些想要深入理解和应用Spring 3.x版本的开发者。这本书通过丰富的实例和详细的代码,帮助读者掌握如何利用Spring进行...

    Spring+3.x企业应用开发实战光盘源码(完全版)

    《Spring+3.x企业应用开发实战》是一本深入讲解如何使用Spring框架进行企业级应用程序开发的书籍。在光盘源码中,包含了从第2章到第19章的全部源代码,这些代码实例覆盖了Spring框架的核心特性和实际应用场景。值得...

    精通Spring2.x企业应用开发详解源代码

    《精通Spring 2.x企业应用开发详解源代码》是一本深度剖析Spring 2.x版本在企业级应用开发中的实践指南。书籍中包含了丰富的实例和源码,旨在帮助开发者深入理解和熟练掌握Spring框架的核心特性和最佳实践。由于资源...

    Cannot load JDBC driver class 'com.microsoft.sqlserver.jdbc.SQLServerDriver'

    5. **IDE或运行环境设置**:如果你在集成开发环境中(如Eclipse、IntelliJ IDEA)工作,确保IDE配置正确,将驱动库包含在构建路径中。如果是服务器环境,比如Tomcat或Jetty,需要把驱动jar_FILE复制到服务器的lib...

    java解决org.springframework.web.context.ContextLoaderListener

    在Java Web开发中,`org.springframework.web.context.ContextLoaderListener` 是Spring框架的一部分,它负责初始化一个Web应用程序的Spring上下文。这个监听器是基于Servlet容器(如Tomcat、Jetty等)的,当Web应用...

    Spring+3.x企业应用开发实战光盘maven整合代码

    《Spring+3.x企业应用开发实战光盘maven整合代码》是针对Spring 3.x版本在企业级项目中应用的实战教程,其中包含了如何利用Maven进行项目构建和管理依赖的过程。在这个压缩包中,主要文件名为"spring3.x",意味着它...

    深入分析Spring源码.docx

    《深入分析Spring源码》 Spring框架作为Java领域最广泛使用的框架之一,其设计思想和实现方式对于开发者来说具有极高的学习价值。本篇将详细探讨Spring中运用的设计模式及其重要性。 首先,Spring框架中广泛应用了...

    Spring-Framework-5.2.x Maven版本

    - **JDBC增强**:Spring JDBC模块在5.2.x版本中进行了优化,支持了更多的JDBC 4.2规范特性,如SQL注解、结果集映射等,同时提供了更好的事务管理和异常处理。 - **Java 11支持**:Spring 5.2.x开始支持Java 11,这...

    官方原版源码 spring-5.2.8.RELEASE.zip

    本文将对这个版本的源码进行深入剖析,帮助读者更好地理解和利用Spring框架。 首先,源码分析通常从项目结构开始。在解压后的文件中,我们看到有三个主要的子文件:`spring-5.2.8.RELEASE-dist.zip`、`spring-5.2.8...

    Spring 3.x企业应用开发实战.pdf(高清版)

    根据提供的文件信息,“Spring 3.x企业应用开发实战.pdf(高清版)”这份文档主要聚焦于Spring框架在企业级应用中的开发与实践。Spring框架是一个开源的Java平台,用于简化企业级应用程序的开发,它提供了全面的基础...

    com.microsoft.sqlserver.jdbc.SQLServerException: 只进结果集不支持请求的操作 解决方案

    ### 异常根本原因分析 此异常通常发生在使用JDBC驱动连接SQL Server数据库并尝试执行某些操作(如分页)时。具体而言,当使用`setFirstResult()`和`setMaxResults()`方法对查询结果集进行限制时,如果结果集被标记...

    spring-5.1.x_ch(含文档).zip

    10. **文档与学习资源**:Spring 5.1.x 随带的中文文档覆盖了所有核心模块,详尽阐述了每个特性的使用方法和原理,为开发者提供了一手的学习资料。 通过深入学习 Spring 5.1.x 的源码,开发者不仅可以掌握这一强大...

    spring-framwork-5.1.x:建造好的spring5.1.x源码阅读环境

    通过阅读和分析源码,你将能更好地掌握Spring框架的设计思想,提升自己的编程技能和解决问题的能力。 总之,"spring-framework-5.1.x"压缩包提供了一个完整的Spring 5.1.x源码环境,对于想要深入了解Spring框架、...

    精通Spring+4.x++企业应用开发实战及源码

    3. **数据访问**:深入探讨Spring与JDBC、ORM框架如Hibernate和MyBatis的整合,以及对JPA的支持,包括事务策略和数据源配置。 4. **Web开发**:讲解MVC框架的使用,包括控制器、视图解析、模型数据传递,以及如何...

    weblogic.jdbc.wrapper.Clob_oracle_sql_CLOB 类型转换解决办法

    3. **CLOB 数据读取**:无论是 `oracle.sql.CLOB` 还是通过 `getVendorObj()` 方法得到的 `oracle.sql.CLOB` 对象,都可以通过 `getAsciiStream()` 和 `getSubString()` 方法来读取 CLOB 的内容,并将其转换为字符串...

    impala数据库JDBC驱动集

    Impala是Cloudera公司开发的一种高性能、实时分析数据库,它是Apache Hadoop生态系统的一部分,专为大规模数据...同时,由于JDBC的标准化,开发者可以利用熟悉的Java工具和框架,如Spring JDBC,来进一步简化开发过程。

Global site tag (gtag.js) - Google Analytics