暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mybatis框架分析之实现自己的framework(加篇)

Alleria Windrunner 2020-01-16
179
继续撸代码咯,到上篇为止我们还剩最后的sql之行部分没有写完,本篇我们就来完成:
    package com.eleven.session;


    import com.eleven.config.*;


    import javax.sql.DataSource;
    import java.lang.reflect.Field;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.util.ArrayList;
    import java.util.List;


    /**
    * sql执行器默认实现类
    * @author eleven
    * @see
    * @since
    */


    public class SimpleExecutor implements Executor {


    private static final String PREPARED = "prepared";


    @Override
    public List<Object> query(Configuration configuration, MappedStatement mappedStatement, Object param) {
    List<Object> results = new ArrayList<>();
    Connection connection = null;
    try {
    // 获取连接
    // 先从Configuration对象中获取DataSource(到底是C3P0还是Dbcp还是其他的)
    DataSource dataSource = configuration.getDataSource();
    // 从DataSource获取连接
    connection = dataSource.getConnection();
    // 执行Statement
    // 先从Configuration对象中根据statementId获取MappedStatement对象(SQL语句等)
    String statementType = mappedStatement.getStatementType();
    statementType = statementType == null || statementType.equals("") ? "prepared" : statementType;
    if (PREPARED.equals(statementType)) {
    handlePreparedStatement(results, mappedStatement, connection, param);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    return results;
    }


    private void handlePreparedStatement(List<Object> results, MappedStatement mappedStatement, Connection connection,
    Object param) throws Exception {
    // 通过MappedStatement对象,获取SQL语句(需要特殊处理)
    BoundSql boundSql = getBoundSql(mappedStatement, param);
    // 通过MappedStatement对象,获取statementType字段
    // 创建Statement(JDBC包含三种Statement:Statement、PreparedStatement、CallableStatement)
    PreparedStatement statement = connection.prepareStatement(boundSql.getSql());
    // 设置参数
    // 获取SQL语句对应的参数信息List<ParameterMapping>
    handleParameter(statement, param, boundSql.getParameterMappings());
    // 执行statement
    ResultSet resultSet = statement.executeQuery();
    // 处理结果
    Class<?> resultTypeClass = mappedStatement.getResultType();
    handleReturnValue(results, resultSet, resultTypeClass);
    }


    private void handleReturnValue(List<Object> results, ResultSet resultSet, Class<?> resultTypeClass)
    throws Exception {
    while (resultSet.next()) {
    Object result = resultTypeClass.newInstance();
    ResultSetMetaData metaData = resultSet.getMetaData();
    int columnCount = metaData.getColumnCount();


    for (int i = 1; i <= columnCount; i++) {
    String columnName = metaData.getColumnName(i);
    Field field = resultTypeClass.getDeclaredField(columnName);
    field.setAccessible(true);
    field.set(result, resultSet.getObject(columnName));
    }
    results.add(result);
    }
    }


    private void handleParameter(PreparedStatement statement, Object param, List<ParameterMapping> parameterMappings)
    throws Exception {
    if (param instanceof Integer) {
    statement.setObject(1, param);
    } else if (param instanceof String) {
    statement.setObject(1, param);
    } else {
    Class<?> clazz = param.getClass();
    for (int i = 0; i < parameterMappings.size(); i++) {
    ParameterMapping parameterMapping = parameterMappings.get(i);
    String name = parameterMapping.getName();
    Field field = clazz.getDeclaredField(name);
    field.setAccessible(true);
    Object value = field.get(param);
    statement.setObject(i + 1, value);
    }
    }
    }


    private BoundSql getBoundSql(MappedStatement mappedStatement, Object param) {
    SqlSource sqlSource = mappedStatement.getSqlSource();
    return sqlSource.getBoundSql();
    }
    }
    代码总共分成以下几块:
    1. 获取连接

    2. 执行statement

      1. 创建Statement

      2. 设置参数

      3. 执行statement


    另外这里借助了mybatis框架的几个工具类:
    1. GenericTokenParser

    2. TokenHandler

    3. ParameterMappingTokenHandler


    到此为止,我们自己的framework就完成了,主要实现的流程为:
    1. 配置文件加载

    2. sqlSession执行

    文章转载自Alleria Windrunner,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论