转载:博客主页:http://blog.csdn.NET/chszs

一、概述

在Spring JDBC模块中,所有的类可以被分到四个单独的包:
1)core
即核心包,它包含了JDBC的核心功能。此包内有很多重要的类,包括:JdbcTemplate类、SimpleJdbcInsert类,SimpleJdbcCall类,以及NamedParameterJdbcTemplate类。
2)datasource
即数据源包,访问数据源的实用工具类。它有多种数据源的实现,可以在JavaEE容器外部测试JDBC代码。
3)object
即对象包,以面向对象的方式访问数据库。它允许执行查询并返回结果作为业务对象。它可以在数据表的列和业务对象的属性之间映射查询结果。
4)support
即支持包,是core包和object包的支持类。例如提供了异常转换功能的SQLException类。

二、配置
下面我们以MySQL数据库为例,开始简单的数据源配置:

  1. @Configuration
  2. @ComponentScan("com.ch.myalbumjdbc")
  3. public class SpringJdbcConfig {
  4. @Bean
  5. public DataSource mysqlDataSource() {
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource();
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql://localhost:3306/springjdbc");
  9. dataSource.setUsername("guest_user");
  10. dataSource.setPassword("guest_password");
  11. return dataSource;
  12. }
  13. }

或者,您还可以利用嵌入式数据库进行开发或测试,比如用HSQL嵌入式数据库进行快速配置并创建实例:

  1. @Bean
  2. public DataSource dataSource() {
  3. return new EmbeddedDatabaseBuilder()
  4. .setType(EmbeddedDatabaseType.HSQL)
  5. .addScript("classpath:jdbc/schema.sql")
  6. .addScript("classpath:jdbc/test-data.sql").build();
  7. }

最后,也可以使用XML配置来实现前面的注释配置的效果:

  1. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  2. destroy-method="close">
  3. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  4. <property name="url" value="jdbc:mysql://localhost:3306/springjdbc"/>
  5. <property name="username" value="guest_user"/>
  6. <property name="password" value="guest_password"/>
  7. </bean>

三、JdbcTemplate的使用和运行查询
1、基本的查询
JDBC模板是Spring JDBC模块中主要的API,它提供了常见的数据库访问功能:

  1. int result = jdbcTemplate.queryForObject(
  2. "SELECT COUNT(*) FROM EMPLOYEE", Integer.class);

下面是简单的插入功能:

  1. public int addEmplyee(int id) {
  2. return jdbcTemplate.update(
  3. "INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", 5, "Bill", "Gates", "USA");
  4. }

注意提供参数的标准语法——使用“?”字符。下面,让我们看看替代语法。

2、查询与命名参数
要获得命名参数的支持,我们需要使用Spring JDBC提供的其它JDBC模板——NamedParameterJdbcTemplate。
此类封装了JbdcTemplate,并提供了使用“?”来替代指定参数的传统语法。它使用传递的参数来替换占位符“?”,以执行传参的查询:

  1. SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("id", 1);
  2. return namedParameterJdbcTemplate.queryForObject(
  3. "SELECT FIRST_NAME FROM EMPLOYEE WHERE ID = :id", namedParameters, String.class);

请注意,我们使用的是MapSqlParameterSource来提供值的命名参数。
下面是使用bean类的属性来确定命名参数简单例子:

  1. Employee employee = new Employee();
  2. employee.setFirstName("James");
  3. String SELECT_BY_ID = "SELECT COUNT(*) FROM EMPLOYEE WHERE FIRST_NAME = :firstName";
  4. SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(employee);
  5. return namedParameterJdbcTemplate.queryForObject(SELECT_BY_ID, namedParameters, Integer.class);

请注意,我们是怎样利用BeanPropertySqlParameterSource的实现来替代指定的命名参数。

3、把查询结果映射到Java对象
还有一个非常有用的功能是把查询结果映射到Java对象——通过实现RowMapper接口。
例如,对于查询返回的每一行结果,Spring会使用该行映射来填充Java bean:

  1. public class EmployeeRowMapper implements RowMapper<Employee> {
  2. @Override
  3. public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
  4. Employee employee = new Employee();
  5. employee.setId(rs.getInt("ID"));
  6. employee.setFirstName(rs.getString("FIRST_NAME"));
  7. employee.setLastName(rs.getString("LAST_NAME"));
  8. employee.setAddress(rs.getString("ADDRESS"));
  9. return employee;
  10. }
  11. }

现在,我们传递行映射器给查询API,并得到完全填充好的Java对象:

  1. String query = "SELECT * FROM EMPLOYEE WHERE ID = ?";
  2. List<Employee> employees = jdbcTemplate.queryForObject(
  3. query, new Object[] { id }, new EmployeeRowMapper());

四、异常转换
Spring提供了自己的开箱即用的数据异常分层——DataAccessException作为根异常,它负责转换所有的原始异常。
所以开发者无需处理底层的持久化异常,因为Spring JDBC模块已经在DataAccessException类及其子类中封装了底层的异常。
这样可以使异常处理机制独立于当前使用的具体数据库。
除了默认的SQLErrorCodeSQLExceptionTranslator类,开发者也可以提供自己的SQLExceptionTranslator实现。
下面是一个自定义SQLExceptionTranslator实现的简单例子,当出现完整性约束错误时自定义错误消息:

  1. public class CustomSQLErrorCodeTranslator extends SQLErrorCodeSQLExceptionTranslator {
  2. @Override
  3. protected DataAccessException customTranslate
  4. (String task, String sql, SQLException sqlException) {
  5. if (sqlException.getErrorCode() == -104) {
  6. return new DuplicateKeyException(
  7. "Custom Exception translator - Integrity constraint violation.", sqlException);
  8. }
  9. return null;
  10. }
  11. }

要使用自定义的异常转换器,我们需要把它传递给JdbcTemplate——通过callingsetExceptionTranslator()方法:

  1. CustomSQLErrorCodeTranslator customSQLErrorCodeTranslator = new CustomSQLErrorCodeTranslator();
  2. jdbcTemplate.setExceptionTranslator(customSQLErrorCodeTranslator);

五、使用SimpleJdbc类实现JDBC操作
SimpleJdbc类提供简单的方法来配置和执行SQL语句。这些类使用数据库的元数据来构建基本的查询。 SimpleJdbcInsert类和SimpleJdbcCall类提供了更简单的方式来执行插入和存储过程的调用。
1、SimpleJdbcInsert类
下面,让我们来看看执行简单的插入语句的最低配置,基于SimpleJdbcInsert类的配置产生的INSERT语句。
所有您需要提供的是:表名、列名和值。让我们先创建SimpleJdbcInsert:

  1. SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("EMPLOYEE");

现在,让我们提供列名和值,并执行操作:

  1. public int addEmplyee(Employee emp) {
  2. Map<String, Object> parameters = new HashMap<String, Object>();
  3. parameters.put("ID", emp.getId());
  4. parameters.put("FIRST_NAME", emp.getFirstName());
  5. parameters.put("LAST_NAME", emp.getLastName());
  6. parameters.put("ADDRESS", emp.getAddress());
  7. return simpleJdbcInsert.execute(parameters);
  8. }

为了让数据库生成主键,我们可以使用executeAndReturnKey() API,我们还需要配置的实际自动生成的列:

  1. SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
  2. .withTableName("EMPLOYEE")
  3. .usingGeneratedKeyColumns("ID");
  4. Number id = simpleJdbcInsert.executeAndReturnKey(parameters);
  5. System.out.println("Generated id - " + id.longValue());

最后,我们还能使用BeanPropertySqlParameterSource和MapSqlParameterSource传递数据。

2、用SimpleJdbcCall调用存储过程
让我们看看如何执行存储过程——我们使用SimpleJdbcCall的抽象:

  1. SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource)
  2. .withProcedureName("READ_EMPLOYEE");
  3. public Employee getEmployeeUsingSimpleJdbcCall(int id) {
  4. SqlParameterSource in = new MapSqlParameterSource().addValue("in_id", id);
  5. Map<String, Object> out = simpleJdbcCall.execute(in);
  6. Employee emp = new Employee();
  7. emp.setFirstName((String) out.get("FIRST_NAME"));
  8. emp.setLastName((String) out.get("LAST_NAME"));
  9. return emp;
  10. }

六、批处理操作
另一个简单的用例——把多种操作合在一起实现批处理
1、使用JdbcTemplate执行基本的批处理操作
使用JdbcTemplate类,通过batchUpdate() API来执行基本的批处理操作:
注意BatchPreparedStatementSetter实现是很有趣的。

  1. public int[] batchUpdateUsingJdbcTemplate(List<Employee> employees) {
  2. return jdbcTemplate.batchUpdate("INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)",
  3. new BatchPreparedStatementSetter() {
  4. @Override
  5. public void setValues(PreparedStatement ps, int i) throws SQLException {
  6. ps.setInt(1, employees.get(i).getId());
  7. ps.setString(2, employees.get(i).getFirstName());
  8. ps.setString(3, employees.get(i).getLastName());
  9. ps.setString(4, employees.get(i).getAddress();
  10. }
  11. @Override
  12. public int getBatchSize() {
  13. return 50;
  14. }
  15. });
  16. }

2、使用NamedParameterJdbcTemplate执行批处理操作
对于批处理操作,还可以选择使用NamedParameterJdbcTemplate的batchUpdate() API来执行。
此API比先前的更简单——无需实现任何额外的接口来设置参数,因为它有一个内部的预准备语句的setter来传递预设的参数值。
参数值可以通过batchUpdate()方法传递给SqlParameterSource的数组。

  1. SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(employees.toArray());
  2. int[] updateCounts = namedParameterJdbcTemplate.batchUpdate(
  3. "INSERT INTO EMPLOYEE VALUES (:id, :firstName, :lastName, :address)", batch);
  4. return updateCounts;

七、结论
本文讲述了Spring框架中的JDBC抽象,覆盖了Spring JDBC模块内建的各种功能和实际的例子。

Spring JDBC的更多相关文章

  1. spring jdbc 查询结果返回对象、对象列表

    首先,需要了解spring jdbc查询时,有三种回调方式来处理查询的结果集.可以参考 使用spring的JdbcTemplate进行查询的三种回调方式的比较,写得还不错. 1.返回对象(queryF ...

  2. spring jdbc获取插入记录的主键id

    在JDBC3.0规范中,当新增记录时,允许将数据库自动产生的主键值绑定到Statement或PreparedStatement中.使用Statement时,可以通过以下方法绑定主键值: int exe ...

  3. Spring JDBC实现查询

    1 db.properties jdbc.user=root jdbc.password=920614 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbc ...

  4. Spring学习进阶(四) Spring JDBC

    Spring JDBC是Spring所提供的持久层技术.主要目的是降低使用JDBC API的门槛,以一种更直接,更简洁的方式使用JDBC API.在Spring JDBC里用户仅需要做哪些比不可少的事 ...

  5. Spring JDBC常用方法详细示例

    Spring JDBC使用简单,代码简洁明了,非常适合快速开发的小型项目.下面对开发中常用的增删改查等方法逐一示例说明使用方法 1 环境准备 启动MySQL, 创建一个名为test的数据库 创建Mav ...

  6. Spring JDBC 访问MSSQL

    在Spring中对底层的JDBC做了浅层的封装即JdbcTemplate,在访问数据库的DAO层完全可以使用JdbcTemplate完成任何数据访问的操作,接下来我们重点说说Spring JDBC对S ...

  7. Spring JDBC主从数据库配置

    通过昨天学习的自定义配置注释的知识,探索了解一下web主从数据库的配置: 背景:主从数据库:主要是数据上的读写分离: 数据库的读写分离的好处? 1. 将读操作和写操作分离到不同的数据库上,避免主服务器 ...

  8. Spring笔记——Spring+JDBC组合开发

      使用Spring+JDBC集成步骤如下:   1. 配置数据源 2. 配置事务.配置事务时,需要在xml配置文件中引入用于声明事务的tx命名空间,事务的配置方式有两种:注解方式和基于XML配置方式 ...

  9. Spring入门(10)-Spring JDBC

    Spring入门(10)-Spring JDBC 0. 目录 JdbcTemplate介绍 JdbcTemplate常见方法 代码示例 参考资料 1. JdbcTemplate介绍 JdbcTempl ...

随机推荐

  1. zookeeper是什么?原理是什么?【转】

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等.Zookeeper是hadoop的一个子项目,其 ...

  2. Modelsim-altera 仿真 顶层原理图的解决办法

    解决办法:首先需要将.bdf原理图文件转换为Verilog HDL等第三方EDA工具所支持的标准描述文件.在Quartus下,保持*.bdf为活动窗口状态,运行[File]/[Create/Updat ...

  3. AX7: Quick and easy debugging

    This purpose of this blog is to show how you can get quickly get started with debuggingin AX7, speci ...

  4. iOS--KVO的实现原理与具体应用

    本文分为2个部分:概念与应用. 概念部分旨在剖析KVO这一设计模式的实现原理,应用部分通过创建的项目,以说明KVO技术在iOS开发中所带来的作用: 如果是作为是刚接触KVO的初学者,可以在了解基本原理 ...

  5. ios录音、音频播放功能

    #import <AVFoundation/AVFoundation.h> { NSInteger   _timeCount;    NSTimer     *_timer; } @pro ...

  6. JS获取IMG图片高宽

    前段时间在LJW写的touchslider.js轮播代码里添加自适应屏幕大小的功能时,遇到一个问题.不管用什么样的方法都无法获取到IMG标签的高宽,最后只有给图片定一个高宽的比例值:趁今天有空我就写了 ...

  7. Product Backlog

    会议时间:周四中午13:20-14:20 会议地点:寝室 讨论了如何根据用户故事来写排球的程序.如何实现单机模式的基本加分判断胜负的功能.并选出项目测试人员.然后两个人一个小组进行程序基本功能的开发. ...

  8. C#实现获取文本文件的编码的一个类(区分GB2312和UTF8)-来自转载收集

    using System; using System.IO; using System.Text; /// <summary> /// FileEncoding 的摘要说明 /// < ...

  9. jquery easyui校验select下拉列表值是否为空的问题

    属性名 类型 描述 默认值 required 布尔 定义文本域是否为必填项 false validType 字符串 定义字段的验证类型,比如email, url, etc. null missingM ...

  10. THINKPHP中关于接口问题(客户端)

    一 apk版本号 客户端发送get请求访问服务器端的控制器方法,通过用户传过来的用户名和密码. 二  服务器端通过客户端传入的user and password 去数据库进行查询,Success就生成 ...