
- 前言
- 一、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 map = 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);
}
五、MapperMethod
1、execute
解析执行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 Object 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;
}
// 封装参数
六、DefaultSqlSession
会话
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条)