当前位置: 首页 > news >正文

怎么做存储网站辽宁网站建设培训班

怎么做存储网站,辽宁网站建设培训班,建站之星网站模板,中信建设有限责任公司 湖南中筑建设公司1、JDBC的基本操作回顾 这里使用伪代码概括一下流程: 对应数据库版本的驱动包自行下载加载驱动类 (Class.forName(com.mysql.cj.jdbc.Driver))创建Connection连接: conn DriverManager.getConnection(jdbc:mysql://数据库IP:port/数据库名称?useUnico…1、JDBC的基本操作回顾 这里使用伪代码概括一下流程: 对应数据库版本的驱动包自行下载加载驱动类 (Class.forName(com.mysql.cj.jdbc.Driver))创建Connection连接: conn DriverManager.getConnection(jdbc:mysql://数据库IP:port/数据库名称?useUnicodetruecharacterEncodingutf8, 用户名, 用户密码);准备SQL语句: String sql select * from lib_book where book_id ?;创建预处理语句对象 PreparedStatement ps conn.prepareStatement(sql)输入参数处理 // 需要根据参数索引位置和参数类型替换对应占位符索引位置上的为实际的参数值 例如 ps.setInt(1, 12) ps.setInt(1, 10); ps.setString(2, 老人与海);执行SQL语句 查询操作 ResultSet resultSet ps.executeQuery();修改操作 ps.execute();处理返回结果集 while(resultSet.next()){ // 取出一行数据来进行处理映射成java实体类 LibBook book new LibBook(); book.setBookId(resultSet.getLong(1));book.setBookIndexNo(resultSet.getString(2));book.setBookName(resultSet.getString(3));book.setBookAuthor(resultSet.getString(4));book.setBookPublisher(resultSet.getString(6));book.setBookCateId(resultSet.getInt(7));book.setBookStock(resultSet.getInt(8)); }依次关闭打开的所有句柄对象(ResultSet、PreparedStatement、Connection) if(statement ! null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if(conn ! null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}2、Myabtis框架对于JDBC操作的简化 总结一下Mybatis框架的使用流程 1) pom.xml文件中引入Mybatis、日志框架、单元测试框架及数据库驱动依赖2) 编写mybatis-config.xml全局配置文件、日志配置文件3) 编写Mapper层接口4) 编写Mapper层接口对应的xml映射文件 OK搞定。单元测试的使用过程 1) 创建一个SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder factoryBuilder new SqlSessionFactoryBuilder(); 2) 创建一个SqlSessionFactory对象SqlSessionFactory factory factoryBuilder.build(Resources.getResourceAsStream(mybatis-config.xml)); 3) 创建一个SqlSession对象SqlSession sqlSession factory.openSession();4) 获取Mapper层指定接口的动态代理对象LibBookMapper mapper sqlSession.getMapper(LibBookMapper.class);5) 调用接口方法获取返回结果即可 ListLibBook list mapper.selectAllBook();对比操作 我们发现使用Mybatis框架之后我们不需要在关注JDBC的具体操作操作过程了输入参数和返回结果的映射转换 不用我们再手动处理了, 资源的释放也不需要我们手动处理了只需要调用简单的应用层接口就可以完成所有的操作太疯狂了。 但是对于一个合格的开发人员 我们对于框架的API熟练使用 还要对其中的原理清楚了解 这样才能再出现问题时我们可以修改和扩展原有框架完成我们想要的功能 扯远了 今天我们主要来聊一聊Mybatis框架究竟是如何封装JDBC中处理输入参数和返回结果集的类型转换的功能的 3、Myabtis框架的类型转换模块 类型转换模块属于Mybatis框架的基础支撑层模块主要实现数据库中数据和Java对象中的属性的双向映射 主要就是在以下两种场景钟会使用到 1在PreparedStatement为SQL语句绑定参数时需要从Java类型转换为JDBC类型;2从ResultSet结果集中获取数据时则需要从JDBC类型转换为Java类型;3.1 如何完成javaType和JDBCType类型互转 3.2 Mybatis的设计实现 3.2.1 TypeHandler接口 MyBatis框架中提供的所有的类型转换器实现类都继承了TypeHandler接口在TypeHandler接口中定义了类型转换器的最基本的功能(处理输入参数和输出参数)。 /** Copyright 2009-2023 the original author or authors.** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ package org.apache.ibatis.type;import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;/*** author Clinton Begin* 类型处理器*/ public interface TypeHandlerT {/*** 完成SQL语句中实际参数替换占位符的方法*/void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;/*** Gets the result.* 通过数据库列名称从ResultSet中获取结果数据** param rs* the rs* param columnName* Column name, when configuration codeuseColumnLabel/code is codefalse/code* return the result* throws SQLException* the SQL exception*/T getResult(ResultSet rs, String columnName) throws SQLException;/*** 通过数据库列索引从ResultSet中获取结果数据*/T getResult(ResultSet rs, int columnIndex) throws SQLException;/*** 通过数据库列索引从存储过程的执行书写出结果中获取结果数据*/T getResult(CallableStatement cs, int columnIndex) throws SQLException;}3.2.2 BaseTypeHandler实现类 这个基础实现类中只提供了通用了类型转换的基本实现并在原有功能上进行了扩展。 但是对于不同的数据类型的互转还是要根据类型进行针对性处理比如数字类型、字符串类型、日期类型等等处理方法肯定不同mybatis框架提供了这些常用类型的转换器实现 类型处理器Java 类型JDBC 类型BooleanTypeHandlerjava.lang.Boolean, boolean数据库兼容的 BOOLEANByteTypeHandlerjava.lang.Byte, byte数据库兼容的 NUMERIC 或 BYTEShortTypeHandlerjava.lang.Short, short数据库兼容的 NUMERIC 或 SMALLINTIntegerTypeHandlerjava.lang.Integer, int数据库兼容的 NUMERIC 或 INTEGERLongTypeHandlerjava.lang.Long, long数据库兼容的 NUMERIC 或 BIGINTFloatTypeHandlerjava.lang.Float, float数据库兼容的 NUMERIC 或 FLOATDoubleTypeHandlerjava.lang.Double, double数据库兼容的 NUMERIC 或 DOUBLEBigDecimalTypeHandlerjava.math.BigDecimal数据库兼容的 NUMERIC 或 DECIMALStringTypeHandlerjava.lang.StringCHAR, VARCHARClobReaderTypeHandlerjava.io.Reader-ClobTypeHandlerjava.lang.StringCLOB, LONGVARCHARNStringTypeHandlerjava.lang.StringNVARCHAR, NCHARNClobTypeHandlerjava.lang.StringNCLOBBlobInputStreamTypeHandlerjava.io.InputStream-ByteArrayTypeHandlerbyte[]数据库兼容的字节流类型BlobTypeHandlerbyte[]BLOB, LONGVARBINARYDateTypeHandlerjava.util.DateTIMESTAMPDateOnlyTypeHandlerjava.util.DateDATETimeOnlyTypeHandlerjava.util.DateTIMESqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMPSqlDateTypeHandlerjava.sql.DateDATESqlTimeTypeHandlerjava.sql.TimeTIMEObjectTypeHandlerAny OTHER或未指定类型EnumTypeHandlerEnumeration TypeVARCHAR 或任何兼容的字符串类型用来存储枚举的名称而不是索引序数值EnumOrdinalTypeHandlerEnumeration Type任何兼容的 NUMERIC 或 DOUBLE 类型用来存储枚举的序数值而不是名称。SqlxmlTypeHandlerjava.lang.StringSQLXMLInstantTypeHandlerjava.time.InstantTIMESTAMPLocalDateTimeTypeHandlerjava.time.LocalDateTimeTIMESTAMPLocalDateTypeHandlerjava.time.LocalDateDATELocalTimeTypeHandlerjava.time.LocalTimeTIMEOffsetDateTimeTypeHandlerjava.time.OffsetDateTimeTIMESTAMPOffsetTimeTypeHandlerjava.time.OffsetTimeTIMEZonedDateTimeTypeHandlerjava.time.ZonedDateTimeTIMESTAMPYearTypeHandlerjava.time.YearINTEGERMonthTypeHandlerjava.time.MonthINTEGERYearMonthTypeHandlerjava.time.YearMonthVARCHAR 或 LONGVARCHARJapaneseDateTypeHandlerjava.time.chrono.JapaneseDateDATE 这里通过一个具体的基础数据类型BooleanTypeHandler类来进行说明 /** Copyright 2009-2022 the original author or authors.** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ package org.apache.ibatis.type;import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;/*** author Clinton Begin*/ public class BooleanTypeHandler extends BaseTypeHandlerBoolean {/*** 预处理语句中的非null参数转换(null参数在哪里处理的呢 在父类BaseTypeHandler里面处理了)*/Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType)throws SQLException {ps.setBoolean(i, parameter);}/*** ResultSet结果集里面jdbcType返回为null时通过调用该方法传递列名方式转换成Java类中对应属性的javaType*/Overridepublic Boolean getNullableResult(ResultSet rs, String columnName)throws SQLException {boolean result rs.getBoolean(columnName);return !result rs.wasNull() ? null : result;}/*** ResultSet结果集里面jdbcType返回为null时通过调用该方法传递列索引方式转换成Java类中对应属性的javaType*/Overridepublic Boolean getNullableResult(ResultSet rs, int columnIndex)throws SQLException {boolean result rs.getBoolean(columnIndex);return !result rs.wasNull() ? null : result;}/*** 存储过程执行结果转换成javaType类型*/Overridepublic Boolean getNullableResult(CallableStatement cs, int columnIndex)throws SQLException {boolean result cs.getBoolean(columnIndex);return !result cs.wasNull() ? null : result;} }3.2.3 TypeHandlerRegistry注册器 Mybatis框架提供了很多的类型转换器实现给我们使用 这些类型转换器对象肯定不是需要我们自己进行创建的 肯定是在Mybatis集成到我们的项目中时就已经完成所有 默认的类型转换器的实例化的那么Myabtis框架是怎么保存这些对象的么 这些对象又是什么时候完成的实例化操作的么 就是通过 TypeHandlerRegistry类型转换器完成的。 在TypeHandlerRegistry注册器的构造器中完成了java中常用数据类型与jdbc对应数据类型转换时需要用到的TypeHandler类对象的创建和注册 3.2.4 TypeAliasRegistry别名注册器 MyBatis框架的应用的时候会经常用到别名这能大大简化我们的代码其实在MyBatis中是通过TypeAliasRegistry类管理的。在TypeAliasRegistry类的构造方法中会注入系统常见类型的别名。 别名注册器中的核心方法如下 public void registerAlias(String alias, Class? value) {if (alias null) {throw new TypeException(The parameter alias cannot be null);}// issue #748 将别名先转成小写字母String key alias.toLowerCase(Locale.ENGLISH);// 判断别名是否存在if (typeAliases.containsKey(key) typeAliases.get(key) ! null !typeAliases.get(key).equals(value)) {throw new TypeException(The alias alias is already mapped to the value typeAliases.get(key).getName() .);}// 将别名添加到aliasMap集合中去typeAliases.put(key, value);}Mybatis自定义别名注册的两种方式 第一 配置文件方式 (mybatis-config.xml) typeAliasespackage namecom.baidu/ /typeAliases 第二 注解方式 Alias Alias(People) public class SysPeople {private String name; }自定义别名注册也是就是通过这个registerAliases(String packageName, Class? superType) 方法来进行解析注册的。 /*** 通过package指定别名路径和通过Alisa注解来注册别名的方法* 例如我们在全局配置文件中配置的 typeAliases package namecom.baidu//typeAliases 就是通过这个方法来解析处理的* 还有我们使用Alias()注解为类注册的别名都是通过这个方法来完成注册的*/public void registerAliases(String packageName, Class? superType) {ResolverUtilClass? resolverUtil new ResolverUtil();resolverUtil.find(new ResolverUtil.IsA(superType), packageName);SetClass? extends Class? typeSet resolverUtil.getClasses();for (Class? type : typeSet) {// Ignore inner classes and interfaces (including package-info.java)// Skip also inner classes. See issue #6if (!type.isAnonymousClass() !type.isInterface() !type.isMemberClass()) {registerAlias(type);}}}public void registerAlias(Class? type) {String alias type.getSimpleName();Alias aliasAnnotation type.getAnnotation(Alias.class);if (aliasAnnotation ! null) {alias aliasAnnotation.value();}registerAlias(alias, type);}3.2.5 如何自定义类型装换器 你可以重写已有的类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为 实现 org.apache.ibatis.type.TypeHandler 接口 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler 并且可以可选地将它映射到一个 JDBC 类型。 具体的示例官方已经提供了示例代码 有兴趣可以自行观看文档 这里贴上传送门自定义类型转换器文档及示例代码地址https://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers 3.3 Mybatis中Typehandler的应用 不管Mybatis框架还是SQL语句的执行流程经过这么长时间的接触 大家肯定越来越熟悉的 关于SQL语句输入参数的转换及SQL语句执行结果的处理流程节点大家应该能条件反射的说出来 肯定是在SQL语句执行的时候进行处理的 Myabtis框架中执行SQL语句都是依赖Executor来完成的. 关于SQL的参数处理及ResultSet的处理肯定也在这个接口的某个实现类中完成的 这里就不卖关子了 直接亮剑 3.3.1 输入参数处理 主要涉及的核心类就是SimpleExecutor、PreparedStatementHandler和DefaultParameterHandler,来看看每个类中关于输入参数处理的核心方法。 SimpleExecutor SQL语句预处理的核心方法如下 private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {Statement stmt;// 创建数据库连接会话从这里可以看出数据库连接的创建时延迟创建的 在真正使用的时候才会创建这里我们可以做扩展// 数据库的读写分离可以通过这个特性通过扩展实现Connection connection getConnection(statementLog);// 创建预处理SQL语句对象stmt handler.prepare(connection, transaction.getTimeout());// 预处理SQL语句对象中的参数占位符替换处理handler.parameterize(stmt);return stmt;}三件事 1、创建数据库连接会话 2、创建预处理SQL语句对象 3、如果SQL语句中有查询条件使用了参数占位符 就将实际的参数替换成真实的输入参数看看上面这段代码不就是对应JDBC里面这段代码么对不对 只是Mybatis框架做了面向对象层次的封装 其实核心就是上面那三件事。 PreparedStatementHandler 这里省略了关于handler.parameterize()方法的调用过程的解析 直接说明一下吧 就是运用了模板方法模式完成了StatementHandler的参数替换的功能因为MappedStatement的StatementType默认的类型是PREPARED, 所以这里调用的是 PreparedStatementHandler的parameterize()方法接下来看看真正处理输入参数的方法 Overridepublic void parameterize(Statement statement) throws SQLException {parameterHandler.setParameters((PreparedStatement) statement);}上面的方法调用了ParameterHandler接口的setParameters()方法 3.3.2 ParameterHandler对象是什么时候创建的 在SimpleExecutor对象的doQuery()或者doUpdate()方法中调用了创建StatementHanlder、ParameterHandler、ResultSetHandler对象的入口方法如下 Overridepublic E ListE doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {Statement stmt null;try {Configuration configuration ms.getConfiguration();// StatementHanlder、ParameterHandler、ResultSetHandler创建的入口StatementHandler handler configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);// 预处理SQL语句对象创建stmt prepareStatement(handler, ms.getStatementLog());// 执行SQL语句并处理结果后返回return handler.query(stmt, resultHandler);} finally {closeStatement(stmt);}}来看看configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);这个方法 public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {// 创建的statementhandler对象是一个RoutingStatementHandler()对象StatementHandler statementHandler new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);statementHandler (StatementHandler) interceptorChain.pluginAll(statementHandler);return statementHandler;}看看RoutingStatementHandler的构造方法 如下 再看看RoutingStatementHandler的构造方法 如下 再看看BaseStatementHandler的构造方法如下 结论 在创建实际Statement对象对应的StatementHandler时, 完成了ParameterHandler和ResultHandler对象的创建。3.3.3 ParameterHandler/ResultSethandler对象是谁 接着上面往下聊 看看3.3.2 BaseStatementHandler的构造方法中下面两行代码的执行过程 this.parameterHandler configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);this.resultSetHandler configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);Configuration类中对应的方法如下 public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {// 这里我们使用的是**mapper.xml文件声明的SQL语句所以这里的的LanguageDriver肯定是XMLLanguageDriver// XMLLanguageDriver.createParameterHandler()方法会创建一个DefaultParameterHandler对象ParameterHandler parameterHandler mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);// 这里我们可以集成参数处理的插件来扩展入参处理的功能parameterHandler (ParameterHandler) interceptorChain.pluginAll(parameterHandler);return parameterHandler;}public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,ResultHandler resultHandler, BoundSql boundSql) {// Mybatis框架默认创建的就是DefaultResultSetHandler对象 ResultSetHandler resultSetHandler new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);// 这里我们可以集成结果集处理的插件来扩展结果集处理的功能resultSetHandler (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);return resultSetHandler;}结论 如果没有自定义插件 那么Mybatis框架会为我们创建框架提供的默认的DefaultParameterHandler和DefaultResultHandler对象来实现 SQL语句入参和查询结果集ResultSet转换的功能3.3.4 DefaultParameterHandler中入参替换的方法实现 DefaultParameterHandler /*** 替换SQL语句中的占位符为实际传入的参数值的方法*/Overridepublic void setParameters(PreparedStatement ps) {ErrorContext.instance().activity(setting parameters).object(mappedStatement.getParameterMap().getId());// 从BoundSql对象中获取到参数映射对象集合ListParameterMapping parameterMappings boundSql.getParameterMappings();if (parameterMappings ! null) {for (int i 0; i parameterMappings.size(); i) {// 依次取出parameterMapping对象ParameterMapping parameterMapping parameterMappings.get(i);// 保证当前处理的parameterMapping对象都是输入参数if (parameterMapping.getMode() ! ParameterMode.OUT) {Object value;// 获取当前处理的parameterMapping对象的属性名称String propertyName parameterMapping.getProperty();// 如果BoundSql对象的附加参数对象中包含该属性名称 直接从BoundSql对象的附加参数对象中获取到该属性KEY对应的值if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional paramsvalue boundSql.getAdditionalParameter(propertyName);// 如果ParameterObject为空说明没有传值值直接就为null} else if (parameterObject null) {value null;// 如果类型注册器中有该参数对象对应的类型处理器则该参数取值就是parameterObject} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {value parameterObject;// 以上都不满足就创建一个元数据对象然后从元数据对象汇总通过属性获取到对应的取值} else {MetaObject metaObject configuration.newMetaObject(parameterObject);value metaObject.getValue(propertyName);}// 获取当前parameterMapping对象的类型处理器TypeHandler typeHandler parameterMapping.getTypeHandler();// 获取当前parameterMapping对象的JDBC数据类型JdbcType jdbcType parameterMapping.getJdbcType();// 如果参数输入值为null并且数据库数据类型为null,就将jdbcType类型设置为OTHER类型if (value null jdbcType null) {jdbcType configuration.getJdbcTypeForNull();}try {// 为什么这里是使用i 1?// insert into t_user(name, age, gender, email) value(?, ?, ?, ?)// 因为解析出来的带占位的sql语法中的?参数的计数是从1开始的 不是从0开始的// 调用typeHandler的替换参数的方法替换到SQL语句中目标位置上占位符上为输入的参数值typeHandler.setParameter(ps, i 1, value, jdbcType);} catch (TypeException | SQLException e) {throw new TypeException(Could not set parameters for mapping: parameterMapping . Cause: e, e);}}}}}3.3.5 输出结果处理 主要涉及的核心类就是SimpleExecutor、PreparedStatementHandler和DefaultResultSetHandler,来看看每个类中关于查询结果集ResultSet处理的核心方法。 SimpleExecutor Overridepublic E ListE doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {Statement stmt null;try {Configuration configuration ms.getConfiguration();StatementHandler handler configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);stmt prepareStatement(handler, ms.getStatementLog());// 调用Statementhandler的query()方法执行查询获取查询结果return handler.query(stmt, resultHandler);} finally {closeStatement(stmt);}}PreparedStatementHandler 调用resultSetHandler.handleResultSets(ps)方法处理查询结果集ResultSet Overridepublic E ListE query(Statement statement, ResultHandler resultHandler) throws SQLException {PreparedStatement ps (PreparedStatement) statement;ps.execute();// 调用DefaultResultHandler的handleResultSets方法处理SQL语句的执行结果return resultSetHandler.handleResultSets(ps);}3.3.6 DefaultResultSetHandler中ResultSet结果集转换的方法实现 handleResultSets()方法 //// HANDLE RESULT SETS//Overridepublic ListObject handleResultSets(Statement stmt) throws SQLException {ErrorContext.instance().activity(handling results).object(mappedStatement.getId());final ListObject multipleResults new ArrayList();int resultSetCount 0;ResultSetWrapper rsw getFirstResultSet(stmt);ListResultMap resultMaps mappedStatement.getResultMaps();int resultMapCount resultMaps.size();validateResultMapsCount(rsw, resultMapCount);while (rsw ! null resultMapCount resultSetCount) {ResultMap resultMap resultMaps.get(resultSetCount);// 处理每一行数据从ResultSet转换成java实体类的方法handleResultSet(rsw, resultMap, multipleResults, null);rsw getNextResultSet(stmt);cleanUpAfterHandlingResultSet();resultSetCount;}String[] resultSets mappedStatement.getResultSets();if (resultSets ! null) {while (rsw ! null resultSetCount resultSets.length) {ResultMapping parentMapping nextResultMaps.get(resultSets[resultSetCount]);if (parentMapping ! null) {String nestedResultMapId parentMapping.getNestedResultMapId();ResultMap resultMap configuration.getResultMap(nestedResultMapId);handleResultSet(rsw, resultMap, null, parentMapping);}rsw getNextResultSet(stmt);cleanUpAfterHandlingResultSet();resultSetCount;}}return collapseSingleResultList(multipleResults);}处理每一行数据从ResultSet转换成java实体类的方法 //// GET VALUE FROM ROW FOR NESTED RESULT MAP//private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, String columnPrefix, Object partialObject) throws SQLException {final String resultMapId resultMap.getId();Object rowValue partialObject;if (rowValue ! null) {final MetaObject metaObject configuration.newMetaObject(rowValue);putAncestor(rowValue, resultMapId);applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);ancestorObjects.remove(resultMapId);} else {final ResultLoaderMap lazyLoader new ResultLoaderMap();rowValue createResultObject(rsw, resultMap, lazyLoader, columnPrefix);if (rowValue ! null !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {final MetaObject metaObject configuration.newMetaObject(rowValue);boolean foundValues this.useConstructorMappings;if (shouldApplyAutomaticMappings(resultMap, true)) {// 自动完成jdbcType到javaType的映射foundValues applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;}// 如果数据库字段和实体类属性无法自动映射 需要通过该方法完成转换foundValues applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;putAncestor(rowValue, resultMapId);// 如果存在关联查询时 需要完成来自其他数据表的ResultSet的转换处理foundValues applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;ancestorObjects.remove(resultMapId);foundValues lazyLoader.size() 0 || foundValues;rowValue foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;}if (combinedKey ! CacheKey.NULL_CACHE_KEY) {nestedResultObjects.put(combinedKey, rowValue);}}return rowValue;}可以自动映射时根据对应的TypeHandler返回对应类型的值。 private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {ListUnMappedColumnAutoMapping autoMapping createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);boolean foundValues false;if (!autoMapping.isEmpty()) {for (UnMappedColumnAutoMapping mapping : autoMapping) {final Object value mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);if (value ! null) {foundValues true;}if (value ! null || (configuration.isCallSettersOnNulls() !mapping.primitive)) {// gcode issue #377, call setter on nulls (value is not found)metaObject.setValue(mapping.property, value);}}}return foundValues;}根据Property调用对应的TypeHandler返回对应类型的值。 private Object getPropertyMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix)throws SQLException {if (propertyMapping.getNestedQueryId() ! null) {return getNestedQueryMappingValue(rs, metaResultObject, propertyMapping, lazyLoader, columnPrefix);} else if (propertyMapping.getResultSet() ! null) {addPendingChildRelation(rs, metaResultObject, propertyMapping); // TODO is that OK?return DEFERRED;} else {final TypeHandler? typeHandler propertyMapping.getTypeHandler();final String column prependPrefix(propertyMapping.getColumn(), columnPrefix);return typeHandler.getResult(rs, column);}}
http://www.dnsts.com.cn/news/171205.html

相关文章:

  • 网站改版 百度影响网站建设详细报价
  • 济南手机网站开发公司电话深圳办公室装修效果图
  • 平阳网站建设公司推荐几个设计网站
  • 怎样使自己做的网站上线图片上传网站变形的处理
  • 网站设计基本结构网站后台登陆网址是多少
  • 哪些网站可以做引流建设公司网站的可行性研究
  • 制作介绍的网站模板广州注册公司最新流程
  • wordpress手机网站模版wordpress 去掉超链接
  • 程序员用来做笔记的网站如何获取公众号
  • 仿牌网站空间商城系统管理
  • 建筑工程找工作哪个网站好网推获客平台
  • 销售类网站开发架构全球十大软件公司
  • 网站制作学校要的360免费wifi怎么连接
  • 山东省专业群建设网站html实例
  • 校园网建设网站特色好的网站你知道
  • 多语言网站建设推广WordPress论坛案例
  • 中文域名网站好不好优化自己的网站怎么做搜索
  • asp.net 网站修改发布网站开发规划书怎么写
  • 互动平台是什么意思深圳市企业网站seo
  • 怎么用.net做网站建工论坛网
  • 10_10_设计公司网站设计网站开发培训学院
  • 福州企业自助建站手机网站有什么区别
  • 如何申请建设网站域名郑州做品牌网站的公司
  • 苏州新区建网站百度竞价关键词查询
  • 网站的特征包括哪些什么颜色做网站好看
  • 常德网站seo作业做哪些类型的网站
  • 网站后台管理需求余杭网站建设
  • 网站建设文化服务西安市高新区建设局网站
  • 成都网络运营公司seo搜索排名影响因素主要有
  • 推荐盐城网站建设绍兴建设网站制作