Mybatis3源码分析(15)-Sql解析执行-Statement初始化和参数设置
2015-12-22 13:11
1031 查看
在SimpleExecutor中,执行SQL时调用preareStatement()方法来对statement进行初始化及参数设置。
这里PreparedStatementHandler为例。详细分析这两个过程。
设置sql执行时的参数
从结果集中取数据
这些都Mybatis内置的TypeHandler,我们也可以自定义一个!处置枚举类型可能很有用。具体的TypeHandler不做讨论。
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException { Statement stmt; Connection connection = getConnection(statementLog); //初始化 stmt = handler.prepare(connection); //参数设置` handler.parameterize(stmt); return stmt; }
这里PreparedStatementHandler为例。详细分析这两个过程。
Statement初始化
这是BaseStatementHandler.prepare()方法public Statement prepare(Connection connection) throws SQLException { ErrorContext.instance().sql(boundSql.getSql()); Statement statement = null; try { //通过connection得到一个statement statement = instantiateStatement(connection); //设置执行超时时间 setStatementTimeout(statement); setFetchSize(statement); return statement; } catch (SQLException e) { closeStatement(statement); throw e; } catch (Exception e) { closeStatement(statement); throw new ExecutorException("Error preparing statement. Cause: " + e, e); } }再看PreparedStatementHandler.instantiateStatement()方法
protected Statement instantiateStatement(Connection connection) throws SQLException { //被执行的SQL String sql = boundSql.getSql(); if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) { String[] keyColumnNames = mappedStatement.getKeyColumns(); if (keyColumnNames == null) { return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); } else { return connection.prepareStatement(sql, keyColumnNames); } } else if (mappedStatement.getResultSetType() != null) { return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY); } else { //直接使用jdbc的方式获取了一个PreparedStatement对象 return connection.prepareStatement(sql); } }
Statement参数设置
如下是PreparedStatementHandler.parameterize()方法public void parameterize(Statement statement) throws SQLException { //直接调用了ParameterHandler的方法设置 parameterHandler.setParameters((PreparedStatement) statement); }DefaultParamterHandler.parameterize()方法
public void setParameters(PreparedStatement ps) throws SQLException { ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId()); //取出sql中的参数映射列表 List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings != null) { for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params value = boundSql.getAdditionalParameter(propertyName); } else if (parameterObject == null) { value = null; } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else { //主要通过MetaObject对象从参数出取数据,MetaObject前面已经详细分析过! MetaObject metaObject = configuration.newMetaObject(parameterObject); //根据参数名称获取值 value = metaObject.getValue(propertyName); } TypeHandler typeHandler = parameterMapping.getTypeHandler(); JdbcType jdbcType = parameterMapping.getJdbcType(); if (value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull(); //调用对应的typeHandler设置参数 typeHandler.setParameter(ps, i + 1, value, jdbcType); } } } }TypeHandler主要有两个功能:
设置sql执行时的参数
从结果集中取数据
public interface TypeHandler<T> { //设置参数 void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; //取数据 T getResult(ResultSet rs, String columnName) throws SQLException; //取数据 T getResult(ResultSet rs, int columnIndex) throws SQLException; //取数据 T getResult(CallableStatement cs, int columnIndex) throws SQLException; }来看看类关系图就更清楚啦
这些都Mybatis内置的TypeHandler,我们也可以自定义一个!处置枚举类型可能很有用。具体的TypeHandler不做讨论。
小结
分析到这里,如果是执行update/insert/delete语句,那么整个过程基本上已经完成。如果是执行select语句,还有重要的两步:结果集映射及缓存!相关文章推荐
- jdbc中的Statement和PreparedStatement接口对象
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 从源码安装Mysql/Percona 5.5
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- SQL中的三值逻辑
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序