- 前言
- 一、SqlSessionFactoryBuilder
- 1、build
- 二、XMLConfigBuilder
- 1、parse
- 2、parseConfiguration
- 三、DefaultSqlSessionFactory
- 1、openSession
- 2、getMapper
- 四、MapperProxy
- 1、invoke
- 五、MapperMethod
- 1、execute
- 六、DefaultSqlSession
- 1、selectList
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = sqlSessionFactoryBuilder.build(new FileInputStream("")); SqlSession sqlSession = factory.openSession(); EmpHistoryMapper mapper = sqlSession.getMapper(EmpHistoryMapper.class); mapper.findHistoryEmployeeInfoById(1);
Mybais的使用流程大致如上,按如上代码逐步分析
一、SqlSessionFactoryBuilder
解析xml,实例化SessionFactory
1、build解析XML为Cofiguration
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { // 解析XML为document XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); // 将document解析为Configuration return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } // 实例化DefaultSqlSessionFactory public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }二、XMLConfigBuilder
解析document为Configuration
1、parsepublic Configuration parse() { // 如果已经解析过,抛出异常 if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; // 从configuration节点开始解析 parseConfiguration(parser.evalNode("/configuration")); return configuration; }2、parseConfiguration
解析configuration节点
try { //解析properties节点,并设置到configuration得variables属性 propertiesElement(root.evalNode("properties")); //解析setting节点,setting节点用来设置configuration属性,如果setting的属性是configuration没有的属性,则会抛出异常 Properties settings = settingsAsProperties(root.evalNode("settings")); // 设置configuration的vfsImpl loadCustomVfs(settings); // 设置configuration的logImpl-自定义日志实现 loadCustomLogImpl(settings); // 解析typeAliases节点,如果为packeage,则扫描这个包下所有的累,并注册为(类简单名称-class.simpleName,class)到typeAliasRegistry,如果是type,alias,则直接注册 typeAliasesElement(root.evalNode("typeAliases")); // 解析plugins节点,并添加到configuration的interceptors pluginElement(root.evalNode("plugins")); // 解析objectFactory节点,实例化并设置到configuration的objectFacotry,objectFactory用来将查询的数据转为ResutlDTO。 objectFactoryElement(root.evalNode("objectFactory")); // 解析objectWrapperFactory节点,实例化并设置到configuration的objectWrapperFactory objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); // 解析reflectorFactory节点,实例化并设置到configuration的reflectorFactory reflectorFactoryElement(root.evalNode("reflectorFactory")); // 将settings节点的内容设置到configuration,如果settings没有的属性,则设置默认值 settingsElement(settings); // 解析environments节点,将节点的datasource和transactionManager封装为Enviroment并设置到configuration的environment属性 environmentsElement(root.evalNode("environments")); // 解析databaseIdProvider节点,并设置configuration的databaseid为自定义获取的数据库名称 databaseIdProviderElement(root.evalNode("databaseIdProvider")); // 处理typeHandlers节点,结果字段类型转换处理器 typeHandlerElement(root.evalNode("typeHandlers")); // 处理mapper节点 // 1、如果为package类型,则扫描package下的接口生产代理工厂MapperProxyFactory放入到knownMappers,并查找是否有对应的xml,有则解析xml的resultMap,mappedStatement mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); }三、DefaultSqlSessionFactory 1、openSession
实例化Session
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { // 获取执行环境 final Environment environment = configuration.getEnvironment(); // 获取事务工厂 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); // 获取事务 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); // 获取simple类型执行器 final Executor executor = configuration.newExecutor(tx, execType); // 实例化Session return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } // 实例化Exexecutor public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } // 如果允许使用缓存,则由CachingExecutor封装SimpleExecutor if (cacheEnabled) { executor = new CachingExecutor(executor); } // 将所有plugin封装倒executor executor = (Executor) interceptorChain.pluginAll(executor); return executor; }2、getMapper
从kownMapper(前面parseConfiguration解析mapper节点),用全类名获取MapperProxyFactory,由代理工厂创建代理对象MapperProxy
// 获取代理对象 public四、MapperProxyT getMapper(Class type) { return configuration.getMapper(type, this); } public T getMapper(Class type, SqlSession sqlSession) { // 获取代理工厂 final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory ) knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } try { // 实例化代理对象 return mapperProxyFactory.newInstance(sqlSession); } catch (Exception e) { throw new BindingException("Error getting mapper instance. Cause: " + e, e); } } // 实例化代理对象 public T newInstance(SqlSession sqlSession) { final MapperProxy mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache); // JDK反向代理 return newInstance(mapperProxy); }
由于getMapper返回了代理对象,继而执行mapper.findHistoryEmployeeInfoById()方法时会有MapperProxy代理执行
1、invokepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { // 对象类型为object类型,直接原方法执行 if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); // 如果改方法是public非static,非抽象(有方法body)得接口方法即为default修饰的方法,jdk代理执行 } else if (method.isDefault()) { if (privateLookupInMethod == null) { return invokeDefaultMethodJava8(proxy, method, args); } else { return invokeDefaultMethodJava9(proxy, method, args); } } } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } // 实例化MapperMethod final MapperMethod mapperMethod = cachedMapperMethod(method); // return mapperMethod.execute(sqlSession, args); } // 尝试从缓存中获取MapperMethod,没有则实例化MapperMethod private MapperMethod cachedMapperMethod(Method method) { return methodCache.computeIfAbsent(method, k -> new MapperMethod(mapperInterface, method, sqlSession.getConfiguration())); } // 实例化MapperMethod public MapperMethod(Class> mapperInterface, Method method, Configuration config) { // 实例化SqlCommand this.command = new SqlCommand(config, mapperInterface, method); // 实例化MethodSignature this.method = new MethodSignature(config, mapperInterface, method); } // 实例化SqlCommand public SqlCommand(Configuration configuration, Class> mapperInterface, Method method) { final String methodName = method.getName(); final Class> declaringClass = method.getDeclaringClass(); // 根据全类名.方法名从Configuration获取MappedStatement MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass, configuration); //获取不到MappedStatement if (ms == null) { if (method.getAnnotation(Flush.class) != null) { name = null; type = SqlCommandType.FLUSH; } else { // 抛出找不到statement得异常 throw new BindingException("Invalid bound statement (not found): " + mapperInterface.getName() + "." + methodName); } } else { // 设置name和type name = ms.getId(); type = ms.getSqlCommandType(); if (type == SqlCommandType.UNKNOWN) { throw new BindingException("Unknown execution method for: " + name); } } } // 实例化MethodSignature 方法签名 public MethodSignature(Configuration configuration, Class> mapperInterface, Method method) { // 返回类型--处理泛型、数组元素类型 Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface); if (resolvedReturnType instanceof Class>) { this.returnType = (Class>) resolvedReturnType; } else if (resolvedReturnType instanceof ParameterizedType) { this.returnType = (Class>) ((ParameterizedType) resolvedReturnType).getRawType(); } else { this.returnType = method.getReturnType(); } // 返回类型是否void this.returnsVoid = void.class.equals(this.returnType); // 返回类型是否集合 this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray(); // 返回类型是否Cursor this.returnsCursor = Cursor.class.equals(this.returnType); // 返回类型是否Optional this.returnsOptional = Optional.class.equals(this.returnType); // 解析MapKey注解 this.mapKey = getMapKey(method); // 是否有returnsMap this.returnsMap = this.mapKey != null; // 获取类型为RowBounds得参数得索引下标--Page实现了RowBounds this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class); // 获取类型为ResultHandler得参数得索引下标 this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class); // 实例化ParamNameResolver this.paramNameResolver = new ParamNameResolver(configuration, method); } // 实例化ParamNameResolver public ParamNameResolver(Configuration config, Method method) { // 获取方法所有参数类型 final Class>[] paramTypes = method.getParameterTypes(); // 获取方法所有参数注解 final Annotation[][] paramAnnotations = method.getParameterAnnotations(); final SortedMap五、MapperMethod 1、executemap = new TreeMap<>(); // 参数个数 int paramCount = paramAnnotations.length; // get names from @Param annotations-处理被@Param注解得参数 for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { // 跳过RowBounds和ResultHandler if (isSpecialParameter(paramTypes[paramIndex])) { // skip special parameters continue; } String name = null; // 遍历所有注解 for (Annotation annotation : paramAnnotations[paramIndex]) { // 注解为Param if (annotation instanceof Param) { // 标记hasParamAnnotation为true hasParamAnnotation = true; // 设置name为Param的value,参数名称 name = ((Param) annotation).value(); break; } } if (name == null) { // @Param was not specified. -- 设置name获取参数名称 if (config.isUseActualParamName()) { name = getActualParamName(method, paramIndex); } if (name == null) { // use the parameter index as the name ("0", "1", ...) // 设置为当前map大小 // gcode issue #71 name = String.valueOf(map.size()); } } // map<参数索引,参数名称> name可能为Param的value,方法参数名称,数字 map.put(paramIndex, name); } // names <参数索引,参数名称> names = Collections.unmodifiableSortedMap(map); }
解析执行sql
public Object execute(SqlSession sqlSession, Object[] args) { Object result; switch (command.getType()) { ..... // select语句,以下只分析executeForMany case SELECT: if (method.returnsVoid() && method.hasResultHandler()) { executeWithResultHandler(sqlSession, args); result = null; } else if (method.returnsMany()) { // 返回结果为集合 result = executeForMany(sqlSession, args); } else if (method.returnsMap()) {// 返回结果为Map result = executeForMap(sqlSession, args); } else if (method.returnsCursor()) { result = executeForCursor(sqlSession, args); } else { Object param = method.convertArgsToSqlCommandParam(args); result = sqlSession.selectOne(command.getName(), param); if (method.returnsOptional() && (result == null || !method.getReturnType().equals(result.getClass()))) { result = Optional.ofNullable(result); } } break; case FLUSH: result = sqlSession.flushStatements(); break; default: throw new BindingException("Unknown execution method for: " + command.getName()); } if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) { throw new BindingException("Mapper method '" + command.getName() + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; } // 处理返回类型为集合的sql private六、DefaultSqlSessionObject executeForMany(SqlSession sqlSession, Object[] args) { List result; // 封装参数 中的变量#{name} Object param = method.convertArgsToSqlCommandParam(args); // 参数是否RowBounds-Page if (method.hasRowBounds()) { // 获取参数RowBounds RowBounds rowBounds = method.extractRowBounds(args); // 准备执行查询 result = sqlSession.selectList(command.getName(), param, rowBounds); } else { result = sqlSession.selectList(command.getName(), param); } // issue #510 Collections & arrays support if (!method.getReturnType().isAssignableFrom(result.getClass())) { if (method.getReturnType().isArray()) { return convertToArray(result); } else { return convertToDeclaredCollection(sqlSession.getConfiguration(), result); } } return result; } // 封装参数
会话
1、selectList执行返回结果为集合的查询
publicList selectList(String statement, Object parameter, RowBounds rowBounds) { try { // 获取对应的MappedStatement MappedStatement ms = configuration.getMappedStatement(statement); // 由Executor执行查询,这一块本身有缓存的话Executor会被CachingExecutor封装,由于基本不开启缓存,所以从SimpleExecutor分析 return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } // 处理只有一个参数类型为集合并且没有@Param的情 // Collection // Array private Object wrapCollection(final Object object) { if (object instanceof Collection) { StrictMap
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)