博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring JDBC最佳实践(3)
阅读量:6716 次
发布时间:2019-06-25

本文共 6218 字,大约阅读时间需要 20 分钟。

hot3.png

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容器,其初始化工作便可移植到容器的配置文件当中:

com.mysql.jdbc.Driver

之后,想把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());

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

转载于:https://my.oschina.net/u/218421/blog/38598

你可能感兴趣的文章
《面向对象分析与设计》——抽象
查看>>
linux学习记录-------jdk安装配置
查看>>
查看dll依赖项
查看>>
koa和egg项目webpack热更新实现
查看>>
ansible普通用户su切换问题
查看>>
2017.10.1
查看>>
P1965 转圈游戏
查看>>
洛谷——P1187 3D模型
查看>>
温度传感器,ds18b20
查看>>
总结从python2.7和python3.0的语法差异
查看>>
PSP(4.13——4.19)以及周记录
查看>>
ecshop为什么删不掉商品分类
查看>>
spark学习笔记
查看>>
bzoj1941[Sdoi2010]Hide and Seek
查看>>
IT兄弟连 Java Web教程 经典面试题2
查看>>
利用setTimeoutc处理javascript ajax请求超时
查看>>
三、Java基础工具(1)_常用类——字符串
查看>>
文献管理与信息分析》第二讲作业
查看>>
java 遍历arrayList的四种方法
查看>>
根据不同的产品id获得不同的下拉选项 (option传多值)
查看>>