spring jdbc 之一

使用过jdbc的我们都知道spring jdbc ,首先我们看下JdbcTemplate 中的execute
在exceute的实现中看到了数据库进行操作的基本过程,比如需要获得数据库Connection,根据应用对数据库操作需要创建数据库的statement,对数据库操作进行回调,处理数据库异常
最后把数据库的连接关闭,等等,这里展示了使用JDBC完成数据库操作的完整过程,只是在spring中,对这些较为普通的JDBC使用,JdbcTemplate进行了一个封装而已。
public void execute(final String sql)
throws DataAccessException
{

class _cls1ExecuteStatementCallback
implements StatementCallback, SqlProvider
{

public Object doInStatement(Statement stmt)
throws SQLException
{
stmt.execute(sql);
return null;
}

public String getSql()
{
return sql;
}

final JdbcTemplate this$0;
private final String val$sql;

_cls1ExecuteStatementCallback()
{
this$0 = JdbcTemplate.this;
sql = s;
super();
}
}

execute(((StatementCallback) (new _cls1ExecuteStatementCallback())));
}


public Object execute(StatementCallback action)
throws DataAccessException
{
Connection con;
Statement stmt;
Assert.notNull(action, "Callback object must not be null");
con = DataSourceUtils.getConnection(getDataSource());
stmt = null;
Object obj;
try
{
Connection conToUse = con;
if(nativeJdbcExtractor != null && nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements())
conToUse = nativeJdbcExtractor.getNativeConnection(con);
stmt = conToUse.createStatement();
applyStatementSettings(stmt);
Statement stmtToUse = stmt;
if(nativeJdbcExtractor != null)
stmtToUse = nativeJdbcExtractor.getNativeStatement(stmt);
//通过回调函数等到结果
Object result = action.doInStatement(stmtToUse);
handleWarnings(stmt);
obj = result;
}
catch(SQLException ex)
{
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
}
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
return obj;
Exception exception;
exception;
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
throw exception;
}

jdbc的基本原理其中的execute方法,我们在看下jdbcTemplate中的query方法
public Object query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse)
throws DataAccessException
{
return execute(psc, new PreparedStatementCallback() {
public Object doInPreparedStatement(PreparedStatement ps)
throws SQLException
{
ResultSet rs = null;
Object obj;
if(pss != null)
pss.setValues(ps);
rs = ps.executeQuery();
ResultSet rsToUse = rs;
if(nativeJdbcExtractor != null)
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
//采用了接口,进行回调
obj = rse.extractData(rsToUse);
JdbcUtils.closeResultSet(rs);
if(pss instanceof ParameterDisposer)
((ParameterDisposer)pss).cleanupParameters();
return obj;
Exception exception;
exception;
JdbcUtils.closeResultSet(rs);
if(pss instanceof ParameterDisposer)
((ParameterDisposer)pss).cleanupParameters();
throw exception;
}

final JdbcTemplate this$0;
private final PreparedStatementSetter val$pss;
private final ResultSetExtractor val$rse;


{
this$0 = JdbcTemplate.this;
pss = preparedstatementsetter;
rse = resultsetextractor;
super();
}
}
);
}

在对ResultSet进行回调处理的接口有三个,分别为RowMapper,ResultSetExtrator,RowHandlerCallBack接口
RowMapper接口中包含了一个mapRow方法,需要自己实现同通过转换从而得到自己想要的结果。
// 对resultset中封装一个接口为rowMapping
List<VersionInfo> list = jdbcTemplate.query(sql, new
RowMapper<VersionInfo>()
{
@Override
public VersionInfo mapRow(ResultSet rs, int i) throws SQLException
{
VersionInfo versionInfo = new VersionInfo();
versionInfo.setId(rs.getInt("id"));
versionInfo.setVersionName(rs.getString("version_name"));
versionInfo.setUploadTime(rs.getLong("upload_time"));
versionInfo.setActiveState(rs.getString("active_state"));
versionInfo.setVersionType(rs.getString("version_type"));
versionInfo.setFilePath(rs.getString("file_path"));
versionInfo.setReMark(rs.getString("remark"));
versionInfo.setVersionNumber(rs.getString("version_number"));
return versionInfo;
}
});


ResultSetExtrator接口中包含了extractData方法,该方法需要自己遍历Resultset才能得到想要的结果
List<VersionInfo> list = (List<VersionInfo>) jdbcTemplate.query(sql,
new ResultSetExtractor<List<VersionInfo>>()
{
@Override
public List<VersionInfo> extractData(ResultSet rs) throws
SQLException, DataAccessException
{
VersionInfo versionInfo = null;
List<VersionInfo> list = new ArrayList<VersionInfo>();
while (rs.next())
{
versionInfo = new VersionInfo();
versionInfo.setId(rs.getInt("id"));
versionInfo.setVersion_name(rs.getString("version_name"));
versionInfo.setUpload_time(rs.getLong("upload_time"));
versionInfo.setActive_state(rs.getString("active_state"));
versionInfo.setVersion_type(rs.getString("version_type"));
versionInfo.setFile_path(rs.getString("file_path"));
versionInfo.setRemark(rs.getString("remark"));
versionInfo.setVersion_number(rs.getString("version_number"));
list.add(versionInfo);
}
return list;
}
});

RowCallbackHandler接口中包含了processRow方法,该方法中没有返回值,但是会自动的循环ResultSet结果集
final List<VersionInfo> list = new ArrayList<VersionInfo>();
jdbcTemplate.query(sql, new RowCallbackHandler()
{
// 会自动循环ResultSet
@Override
public void processRow(ResultSet rs) throws SQLException
{
VersionInfo versionInfo = new VersionInfo();
versionInfo.setId(rs.getInt("id"));
versionInfo.setVersion_name(rs.getString("version_name"));
versionInfo.setUpload_time(rs.getLong("upload_time"));
versionInfo.setActive_state(rs.getString("active_state"));
versionInfo.setVersion_type(rs.getString("version_type"));
versionInfo.setFile_path(rs.getString("file_path"));
versionInfo.setRemark(rs.getString("remark"));
versionInfo.setVersion_number(rs.getString("version_number"));
list.add(versionInfo);
}
});


可能大家会觉得奇怪,在查询方法中只传入的是ResultSetExtractor接口,而RowMapper和RowCallbackHandler接口与ResultSetExtractor没有相互的集成关系,那么jdbcTemlate是怎样做转换的
首先看下RowCallbackHandler接口

public void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch)
throws DataAccessException
{
query(sql, pss, ((ResultSetExtractor) (new RowCallbackHandlerResultSetExtractor(rch))));
}


//传入的是RowCallbackHandler接口有一个RowCallbackHandlerResultSetExtractor类进行了转换该类实现了ResultSetExtractor接口

private static class RowCallbackHandlerResultSetExtractor
implements ResultSetExtractor
{

public Object extractData(ResultSet rs)
throws SQLException
{
for(; rs.next(); rch.processRow(rs));
return null;
}

private final RowCallbackHandler rch;

public RowCallbackHandlerResultSetExtractor(RowCallbackHandler rch)
{
this.rch = rch;
}
}

同理RowMapper

public class RowMapperResultSetExtractor
implements ResultSetExtractor
{

public RowMapperResultSetExtractor(RowMapper rowMapper)
{
this(rowMapper, 0);
}

public RowMapperResultSetExtractor(RowMapper rowMapper, int rowsExpected)
{
Assert.notNull(rowMapper, "RowMapper is required");
this.rowMapper = rowMapper;
this.rowsExpected = rowsExpected;
}

public List extractData(ResultSet rs)
throws SQLException
{
List results = rowsExpected <= 0 ? ((List) (new ArrayList())) : ((List) (new ArrayList(rowsExpected)));
int rowNum = 0;
for(; rs.next(); results.add(rowMapper.mapRow(rs, rowNum++)));
return results;
}

public volatile Object extractData(ResultSet resultset)
throws SQLException, DataAccessException
{
return extractData(resultset);
}

private final RowMapper rowMapper;
private final int rowsExpected;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值