6.3 query查询处理
查询操作的时候,也会针对语句类型的不同,分别由 SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler (存储过程的,这里不展开讲解)各自实现
SimpleStatementHandler方式
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
String sql = boundSql.getSql(); // 拿到语句
statement.execute(sql); // jdbc 方式的执行语句
// 处理结果,留待`第七章`讲解
return resultSetHandler.handleResultSets(statement);
}
PreparedStatementHandler方式
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute(); // 执行语句
// 处理结果,留待`第七章`讲解
return resultSetHandler.handleResultSets(ps);
}
6.4 update更新处理
SimpleStatementHandler方式
public int update(Statement statement) throws SQLException {
String sql = boundSql.getSql(); // 拿到sql
// 参数
Object parameterObject = boundSql.getParameterObject();
// 章节`3.2.2.7 selectKey解析`中有描述
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
int rows;
// 接下来,都是jdbc的代码了
if (keyGenerator instanceof Jdbc3KeyGenerator) {
statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
rows = statement.getUpdateCount();
keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
} else if (keyGenerator instanceof SelectKeyGenerator) {
statement.execute(sql);
rows = statement.getUpdateCount();
keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
} else {
statement.execute(sql);
rows = statement.getUpdateCount();
}
return rows;
}
PreparedStatementHandler方式
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute(); // jdbc 方式执行
int rows = ps.getUpdateCount(); // 返回的更新行数
// 参数
Object parameterObject = boundSql.getParameterObject();
// 章节`3.2.2.7 selectKey解析`中有描述,这里以 SelectKeyGenerator 举例
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
// 设置处理后的 keyGenerator 的值
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
}
SelectKeyGenerator.processAfter
这一步很简单,就不一行行代码解析了,这个方法的功能就是,在设置配置时各属性的值
public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
if (!executeBefore) {
processGeneratedKeys(executor, ms, parameter);
}
}
private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) {
try {
if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) {
String[] keyProperties = keyStatement.getKeyProperties();
final Configuration configuration = ms.getConfiguration();
final MetaObject metaParam = configuration.newMetaObject(parameter);
if (keyProperties != null) {
// Do not close keyExecutor.
// The transaction will be closed by parent executor.
Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
if (values.size() == 0) {
throw new ExecutorException("SelectKey returned no data.");
} else if (values.size() > 1) {
throw new ExecutorException("SelectKey returned more than one value.");
} else {
MetaObject metaResult = configuration.newMetaObject(values.get(0));
if (keyProperties.length == 1) {
if (metaResult.hasGetter(keyProperties[0])) {
// 看这就行了,设置单个值
setValue(metaParam, keyProperties[0], metaResult.getValue(keyProperties[0]));
} else {
// no getter for the property - maybe just a single value object
// so try that
// 看这就行了,设置单个值
setValue(metaParam, keyProperties[0], values.get(0));
}
} else {
// 设置多个值
handleMultipleProperties(keyProperties, metaParam, metaResult);
}
}
}
}
} catch (ExecutorException e) {
throw e;
} catch (Exception e) {
throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e);
}
}