开篇
这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。
个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。这篇文章讲解Executor的实现类DeleteExecutor。
类依赖图
说明:
- 着重讲解DeleteExecutor实现类。
DeleteExecutor方法介绍
public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecutor<T, S> {
public DeleteExecutor(StatementProxy statementProxy, StatementCallback statementCallback, SQLRecognizer sqlRecognizer) {
super(statementProxy, statementCallback, sqlRecognizer);
}
@Override
protected TableRecords beforeImage() throws SQLException {
SQLDeleteRecognizer visitor = (SQLDeleteRecognizer) sqlRecognizer;
// 获取表的所有的列
TableMeta tmeta = getTableMeta(visitor.getTableName());
List<String> columns = new ArrayList<>();
for (String column : tmeta.getAllColumns().keySet()) {
columns.add(column);
}
// 拼接SELECT的SQL语句
StringBuffer selectSQLAppender = new StringBuffer("SELECT ");
for (int i = 0; i < columns.size(); i++) {
selectSQLAppender.append(getColumnNameInSQL(columns.get(i)));
if (i < (columns.size() - 1)) {
selectSQLAppender.append(", ");
}
}
String whereCondition = null;
// 解析并获取where条件
ArrayList<Object> paramAppender = new ArrayList<>();
if (statementProxy instanceof ParametersHolder) {
whereCondition = visitor.getWhereCondition((ParametersHolder) statementProxy, paramAppender);
} else {
whereCondition = visitor.getWhereCondition();
}
// 拼接SQL的where条件
selectSQLAppender.append(" FROM " + getFromTableInSQL() + " WHERE " + whereCondition + " FOR UPDATE");
String selectSQL = selectSQLAppender.toString();
// 根据拼接的SQL查询数据表获取删除前的数据
TableRecords beforeImage = null;
PreparedStatement ps = null;
Statement st = null;
ResultSet rs = null;
try {
if (paramAppender.isEmpty()) {
st = statementProxy.getConnection().createStatement();
rs = st.executeQuery(selectSQL);
} else {
ps = statementProxy.getConnection().prepareStatement(selectSQL);
for (int i = 0; i< paramAppender.size(); i++) {
ps.setObject(i + 1, paramAppender.get(i));
}
rs = ps.executeQuery();
}
beforeImage = TableRecords.buildRecords(tmeta, rs);
} finally {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (ps != null) {
ps.close();
}
}
return beforeImage;
}
}
说明:
- DeleteExecutor需要保存SQL执行前的镜像。
- 执行前镜像的准备整体思路是按照按照删除条件逆向拼接正向查询SQL。
- 查询的SQL的select的字段直接从查询表的元数据的列值。
- 查询的SQL的条件通过解析delete的条件生成。
- 执行根据delete操作生成的正向select语句查询删除前的数据。
- 根据TableRecords.buildRecords生成执行前镜像。
public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecutor<T, S> {
public DeleteExecutor(StatementProxy statementProxy, StatementCallback statementCallback, SQLRecognizer sqlRecognizer) {
super(statementProxy, statementCallback, sqlRecognizer);
}
@Override
protected TableRecords afterImage(TableRecords beforeImage) throws SQLException {
return TableRecords.empty(getTableMeta());
}
}
说明:
- DeleteExecutor保存的执行后的镜像就是生产空白进行而已。
- TableRecords.empty()方法返回空白镜像。
期待
DeleteExecutor生成执行前后镜像的过程分析完后,会接着分析UpdateExecutor。