spring jdbc 之二

spring jdbcTemplate 提供了很多查询和更新功能,但是如果我们需要高层次的抽象spring还有个RDBMS其中包括了SqlQuery,MappingSqlQuery,SqlUpdate等
我们首先来看下一个简单的查询简单例子
public class BokkQuery extends MappingSqlQuery<VersionInfo>
{
public BokkQuery(DataSource dataSource)
{
super(dataSource, "select * from t_soft_version t where t.id=?");
//设置参数
super.declareParameter(new SqlParameter("id", Types.INTEGER));
compile();
}

@Override
protected VersionInfo mapRow(ResultSet rs, int i) throws SQLException
{
VersionInfo versionInfo = new VersionInfo();
versionInfo.setId(rs.getInt("id"));
versionInfo.setVersion_name(rs.getString("version_name"));
return versionInfo;
}
}

public static void main(String[] args)
{
DataSource dataSource = (DataSource) cxf.getBean("dataSource");
BokkTest test = new BokkTest();
test.listbook(dataSource);
}

public void listbook(DataSource dataSource)
{
BokkQuery bokkQuery = new BokkQuery(dataSource);
List<VersionInfo> list = bokkQuery.execute(new Object[]{11111});
for (VersionInfo versionInfo : list)
{
System.out.println("versionname:" + versionInfo.getVersion_name());
}

}


首先我们看下RdbmsOperation下其类的结构图:



下面我们从declareParameter入手分下一下该功能是如何实现的,其具体的实现在MappingQuery的基类RdbmsOperation的源码可以看到
RdbmsOperation源码如下:
public abstract class RdbmsOperation
implements InitializingBean
{

public void declareParameter(SqlParameter param)
throws InvalidDataAccessApiUsageException
{
//声明参数只能在compile之前,否则声明是无效的,并会抛出异常
if(isCompiled())
{
throw new InvalidDataAccessApiUsageException("Cannot add parameters once the query is compiled");
} else
{
//把参数添加到一个LinkedList集合的属性中,供compile方法使用
declaredParameters.add(param);
return;
}
}

//我们看到了compile
public final void compile()
throws InvalidDataAccessApiUsageException
{
if(!isCompiled())
{
if(getSql() == null)
throw new InvalidDataAccessApiUsageException("Property 'sql' is required");
try
{
//调用了afterPropertesSet方法
jdbcTemplate.afterPropertiesSet();
}
catch(IllegalArgumentException ex)
{
throw new InvalidDataAccessApiUsageException(ex.getMessage());
}
//调用compileInternal完成具体的compile过程,并设置compiled标志位
compileInternal();
compiled = true;
if(logger.isDebugEnabled())
logger.debug((new StringBuilder("RdbmsOperation with SQL [")).append(getSql()).append("] compiled").toString());
}
}

public void afterPropertiesSet()
{
compile();
}
}

compileInternal方法在sqlOperation里完成,在compileInternal中生成一个PreparedStatementCreatorFactory作为Statement的工厂,这个工厂负责生成参数的Statement,其源码如下:

protected final void compileInternal()
{
preparedStatementFactory = new PreparedStatementCreatorFactory(getSql(), getDeclaredParameters());
preparedStatementFactory.setResultSetType(getResultSetType());
preparedStatementFactory.setUpdatableResults(isUpdatableResults());
preparedStatementFactory.setReturnGeneratedKeys(isReturnGeneratedKeys());
if(getGeneratedKeysColumnNames() != null)
preparedStatementFactory.setGeneratedKeysColumnNames(getGeneratedKeysColumnNames());
preparedStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor());
onCompileInternal();
}


在完成compile之后,对MappingSqlQuery的准备工作就基本完成,在执行查询时,实际执行的是SqlQuery的executeByNameParam方法,这个方法需要完成的工作包括配置sql语句,配置数据记录对象转换RowMapper,然后使用JdbcTemplate来完成数据的查询,并启动数据记录到java数据对象的转换,其源码如下:

public List executeByNamedParam(Map paramMap, Map context)
throws DataAccessException
{
validateNamedParameters(paramMap);
//需要执行sql语句
org.springframework.jdbc.core.namedparam.ParsedSql parsedSql = getParsedSql();
MapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap);
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
//配置好SQL语句需要的Paramters即rowMapper,这个Rowmapper完成数据记录对象的转换
Object params[] = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters());
RowMapper rowMapper = new RowMapper(params, context);
//转换成Rowmapper调用的是jdbcTemplate中的模板方法
return getJdbcTemplate().query(newPreparedStatementCreator(sqlToUse, params), rowMapper);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值