原文地址:https://my.oschina.net/u/218421/blog/38598

spring jdbc包提供了JdbcTemplate和它的两个兄弟SimpleJdbcTemplate和NamedParameterJdbcTemplate,我们可以先从JdbcTemplate入手,领略一下这个类的便利和优雅。
1、使用JdbcTemplate进行数据访问:
初始化JdbcTemplate
初始化JdbcTemplate很容易,只需要向它的构造方法传入它所使用的DataSource便可以。如果使用Jakarta Commons DBCP,那么初始化代码如下所示:

BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/mysql?characterEncoding=gb2312");
dataSource.setUsername("***");
dataSource.setPassword("***");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

也可以通过无参的构造方法构造JdbcTemplate,然后通过setDataSource(DataSource dataSource)来设置其dataSource。
上述这种方法是通过编码的方式构造JdbcTemplate,如果应用程序使用spring的IOC容器,其初始化工作便可移植到容器的配置文件当中:

<!-- dataSource -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"> <property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url" value="jdbc:mysql://localhost:3306/oa?characterEncoding=gb2312" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="30" />
<property name="maxWait" value="1000" />
<property name="defaultAutoCommit" value="true" />
<property name="removeAbandoned" value="true" />
</bean>
<!-- jdbcTemplate -->
<bean id="jdbc"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>

之后,想把jdbcTemplate注入到哪个bean都可以,初始化好了JdbcTemplate以后,便可以大施拳脚了!

使用JdbcTemplate查询数据:
JdbcTemplate针对数据查询提供了多个重载的模板方法,我们可以根据需要选用不同的模板方法。如果查询很简单,仅仅是传入相应的SQL或者是相关的参数,然后取得一个结果,那么我们可以用如下的一组便利的模板方法:

public int queryForInt(String sql)
public int queryForInt(String sql, Object[] args)
public int queryForInt(String sql, Object[] args)
public long queryForLong(String sql)
public long queryForLong(String sql, Object[] args)
public long queryForLong(String sql, Object[] args, int[] argTypes)
public Object queryForObject(String sql, Class requiredType)
public Object queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType)
public Object queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper)
public Object queryForObject(String sql, Object[] args, Class requiredType)
public Object queryForObject(String sql, Object[] args, RowMapper rowMapper)
public Object queryForObject(String sql, RowMapper rowMapper)

注意:这些针对的resultset返回的必须是一行记录,否则会出错!
 如果查询的结果包含一列数字型的结果,或者使用了SQL函数,或者其它的单列的结果,那么便可以直接通过这组便利的模板方法进行查询:

int postId = jdbcTemplate.queryForInt("SELECT POSTID FROM USERS WHERE USERNAME=?",new String[]{"jason"});
System.out.println(postId);
long userCount = jdbcTemplate.queryForLong("SELECT COUNT(*) FROM USERS");
System.out.println(userCount);
String nickname = (String)jdbcTemplate.queryForObject("SELECT USERNAME1 FROM USERS WHERE USERNAME='jason'", String.class);
System.out.println(nickname);
Map singleUser = jdbcTemplate.queryForMap("SELECT * FROM USERS WHERE USERNAME = 'jason'");
System.out.println(singleUser);

queryForMap与其它的方法的不同之处在于它的查询的结果以java.util.Map的形式返回,Map的键对应查询的表的列的名字,Map的值对应键所在的列的值。

如果查询的结果返回多行,而我们又不在乎他们是否拥有较强的约束类型,那么可以用以下的模板方法:

public List queryForList(String sql)
public List queryForList(String sql, Object[] args)
public List queryForList(String sql, Object[] args, int[] argTypes)

queryForList()方法根据传入的sql以及相应的参数执行查询,将查询的结果以java.util.List的形式返回,返回的java.util.List中的每个元素都是java.lang.Map类型,分别对应结果集中的一行,Map的键对应每列的列名,Map的值对应当前列名对应的值.

如果这些还不足以满足我们的需要,那么我们可以自己定义回调接口
用于查询的回调接口有以下三种:
org.springframework.jdbc.core.ResultSetExtractor,它是属于JdbcTemplate内部使用的Callback接口,相对于下面的两个接口,这个接口拥有更多的控制权,因为在使用它的时候,我们需要自行的处理ResultSet,该接口的定义如下:

package org.springframework.jdbc.core;

import java.sql.ResultSet;
import java.sql.SQLException; import org.springframework.dao.DataAccessException; public interface ResultSetExtractor { Object extractData(ResultSet rs) throws SQLException, DataAccessException; }

我们可以将处理的结果以任意的形式包装后返回。

org.springframework.jdbc.core.RowCallbackHandler 相对于ResultSetExtractor,它只关注单行结果的处理,处理的结果可以根据需要存放在当前的RowCallbackHandler,或者使用JdbcTemplate中,当然,这完全看个人喜好,接口定义如下:

package org.springframework.jdbc.core;

import java.sql.ResultSet;
import java.sql.SQLException; public interface RowCallbackHandler { void processRow(ResultSet rs) throws SQLException; }

org.springframework.jdbc.core.RowMapper  它是 ResultSetExtractor的精简版,功能类似于 RowCallbackHandler,也是只关注当行结果的处理。不过它的返回的结果会有 ResultSetExtractor实现类进行组合。RowMapper的接口定义如下:

package org.springframework.jdbc.core;

import java.sql.ResultSet;
import java.sql.SQLException; public interface RowMapper { Object mapRow(ResultSet rs, int rowNum) throws SQLException; }

为了说明这三种回调接口的使用方法,我们暂时设置如下的场景: 假设我们有一表users,里面有userid,username,userpwd三个字段,我们为此建立了一个Javabean

package com.google.spring.jdbc;

public class UserBean
{
private Integer userId;
private String username;
private String userpwd;
public Integer getUserId()
{
return userId;
}
public void setUserId(Integer userId)
{
this.userId = userId;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getUserpwd()
{
return userpwd;
}
public void setUserpwd(String userpwd)
{
this.userpwd = userpwd;
} }

使用自定义的ResultSetExtractor,可以如下进行处理:

List users = (List)jdbcTemplate.query("SELECT * FROM USERS WHERE USERNAME LIKE '%n%'", new ResultSetExtractor()
{ @Override
public Object extractData(ResultSet rs) throws SQLException,
DataAccessException
{
List users = new ArrayList();
while(rs.next())
{
UserBean userBean = new UserBean();
userBean.setUserId(rs.getInt("userId"));
userBean.setUsername(rs.getString("username"));
userBean.setUserpwd(rs.getString("userpwd"));
users.add(userBean);
}
return users;
}
});
System.out.println(users);

使用RowMapper,可进行如下的处理:

List users = jdbcTemplate.query("SELECT * FROM USERS WHERE USERNAME LIKE '%n%'", new RowMapper()
{ @Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException
{
UserBean userBean = new UserBean();
userBean.setUserId(rs.getInt("userId"));
userBean.setUsername(rs.getString("username"));
userBean.setUserpwd(rs.getString("userpwd"));
return userBean;
}
});
System.out.println(users.size());

使用RowCallbackHandler可进行如下的处理:

final List users = new ArrayList();
jdbcTemplate.query("SELECT * FROM USERS WHERE USERNAME LIKE '%n%'", new RowCallbackHandler()
{ @Override
public void processRow(ResultSet rs) throws SQLException
{
UserBean userBean = new UserBean();
userBean.setUserId(rs.getInt("userId"));
userBean.setUsername(rs.getString("username"));
userBean.setUserpwd(rs.getString("userpwd"));
users.add(userBean);
}
});
System.out.println(users.size());

使用这三种接口的差别如下:

Spring JDBC最佳实践(3)的更多相关文章

  1. Spring JDBC最佳实践(1)

    原文地址:https://my.oschina.net/u/218421/blog/38513 Spring提供了两种使用JDBC API的最佳实践,一种是以JdbcTemplate为核心的基于Tem ...

  2. Spring JDBC最佳实践(2)

    原文地址:https://my.oschina.net/u/218421/blog/38576 使用DataSourceUtils进行Connection的管理由上节代码可知,JdbcTemplate ...

  3. Spring Validation最佳实践及其实现原理,参数校验没那么简单!

    之前也写过一篇关于Spring Validation使用的文章,不过自我感觉还是浮于表面,本次打算彻底搞懂Spring Validation.本文会详细介绍Spring Validation各种场景下 ...

  4. 微服务电商项目发布重大更新,打造Spring Cloud最佳实践!

    Spring Cloud实战电商项目mall-swarm地址:转发+关注 私信我获取地址 系统架构图   系统架构图 项目组织结构 mall├── mall-common-- 工具类及通用代码模块├─ ...

  5. Spring Boot 16 条最佳实践

    Spring Boot是最流行的用于开发微服务的Java框架.在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践.这些内容是基于我的个人经验和一些熟知的Sp ...

  6. 面试题_76_to_81_Java 最佳实践的面试问题

    包含 Java 中各个部分的最佳实践,如集合,字符串,IO,多线程,错误和异常处理,设计模式等等. 76)Java 中,编写多线程程序的时候你会遵循哪些最佳实践?(答案)这是我在写Java 并发程序的 ...

  7. 开涛spring3(7.5) - 对JDBC的支持 之 7.5 集成Spring JDBC及最佳实践

    7.5 集成Spring JDBC及最佳实践 大多数情况下Spring JDBC都是与IOC容器一起使用.通过配置方式使用Spring JDBC. 而且大部分时间都是使用JdbcTemplate类(或 ...

  8. Spring Boot学习笔记2——基本使用之最佳实践[z]

    前言 在上一篇文章Spring Boot 学习笔记1——初体验之3分钟启动你的Web应用已经对Spring Boot的基本体系与基本使用进行了学习,本文主要目的是更加进一步的来说明对于Spring B ...

  9. spring boot 使用及最佳实践

    第一部分,spring boot 文档 Spring boot的使用 使用maven进行构建 用户可以通过继承spring-boot-starter-parent来获取默认的依赖. l  默认java ...

随机推荐

  1. layui 动态表格设置单元格样式

    col.push({ field: , templet: function (d) { ") { return '<span style="color:white;backg ...

  2. VirtualBox安装Ubutu出错

    今天打算装个虚拟机玩玩,这次没有选择VM.感觉那东西各种破解有点麻烦而且体积也不小呀,所以,这次我选择了稍微点的的VirtualBox. 一路安装虚拟机没有问题,安装完后新建虚拟机都正常,可在启动虚拟 ...

  3. json传的解析,二维数据解析

    下载地址:https://share.weiyun.com/447eda75fdd46cb87f6622ecdce4c3ac

  4. 架构师小跟班:送你一份2019年阿里巴巴最新Java面试题,以供参考

    大家都说大厂面试造飞机,工作拧螺丝.这话只对了一部分,大厂是平时拧螺丝,一旦需要飞机时也能造的起来. 目录 技术一面(23问) 技术二面(3大块) JAVA开发技术面试中可能问到的问题(17问) JA ...

  5. 开发工具--搭建python环境

    工具|搭建python环境 实现python2版本与python3版本的环境搭建. 正文 1.Python下载 官网: www.python.org 下载: ( 64位3.5.2Windows x86 ...

  6. Qt Creator清除最近工程历史信息

    Qt Creator清除最近工程历史信息 随着不断打开和关闭qt工程,欢迎->Projects->Recent projects下的历史工程信息越来越多,是该清理一下了,强迫症会追求干净一 ...

  7. CPU和Memory压力测试方法

    一:用原生Centos自带的工具 1. CPU 下面命令会创建 CPU 负荷,方法是通过压缩随机数据并将结果发送到 /dev/null: cat /dev/urandom | gzip -9 > ...

  8. 【Linux】yum 安装 JDK

    一.查看java的所有版本 yum list java* 二.安装jdk8 yum install java--openjdk.x86_64 三.检查是否安装完成 java -version 四.默认 ...

  9. 【Spring AOP】Spring AOP之你必须知道的AOP相关概念(1)

    一.什么是AOP AOP(Aspect-oriented Programming)即面向切面编程,是对OOP( Object-oriented Programming)即面向对象编程的一种补充,AOP ...

  10. eclipse 将原工作空间配置导入新建工作空间

    相信各位小伙伴使用eclipse开发的时候经常会遇到新建工作空间的时候, 但是每次新建工作空间之后都要重新配置空间.安装插件等等 笔者曾经对此问题很是绝望. . . 后发现新建的工作空间可以导入其他工 ...