如何深度理解mybatis?( 二 )

 三. 深度分析解析SqlSessionFacotryBuild干的核心工作 1. build(InputStream in) 方法做的工作
①借助Dom4j的来解析了xml文件, 将environments解析工作分发给了parseEnvironment(Element environments)
②将mappers的解析工作分发给了parseMapper(Element mapper)
2. parseEnvironment(Element environments)方法做的工作
①主要解析了连接数据库的参数们, 并且创建了数据库连接池
自定义连接池非本章节的重点,所以这里内部本质采用的Druid连接池来做了简化
package com.itheima.ibatis.configuration; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.util.Properties; public class DefaultDataSource { public DataSource getDataSource(Properties properties) { try { return DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } return null; } }
②将解析好的连接池放入configuration对象中,mappers成员变量先别纠结下一章节会讲解
package com.itheima.ibatis.configuration; import lombok.Data; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Data public class Configuration { private Map mappers = new HashMap<>(); private DataSource dataSource; }
详细图解如下图

如何深度理解mybatis?

文章插图
 
3.parseMapper(Element mapper) 方法做的工作
①解析出用户配置的package找到sql语句所在接口的文件夹, 交给initMapper来处理
如何深度理解mybatis?

文章插图
 
②递归找到这个包下所有的.class文件,并且获取到接口的全类名, 然后交给initMapper来处理
如何深度理解mybatis?

文章插图
 
③initMapper通过反射获取类中的每一个方法,将方法交给一个专门解析方法上的注解的工具类ParseMapper的parse方法处理,处理完后将其放到configuration中的mappers的集合中
如何深度理解mybatis?

文章插图
 
④ParseMapper的parse方法做的工作, 这是解析配置的核心地方
package com.itheima.ibatis.configuration; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ParseMapper { public static Mapper parse(Method method) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Annotation[] annotations = method.getAnnotations(); Object value = https://www.isolves.com/it/cxkf/kj/2022-11-14/annotations[0].getClass().getMethod("value").invoke(annotations[0]); Mapper mapper = new Mapper(); Class resultType = method.getReturnType(); String val = (String) value; Pattern pattern = Pattern.compile("/#/{/s*/w+/s*/}"); Matcher matcher = pattern.matcher(val); List paramNames = new ArrayList<>(); while (matcher.find()) { String group = matcher.group(); String fieldName = group.substring(2, group.length() - 1).trim(); paramNames.add(fieldName); } String sql = val.replaceAll("/#/{/s*/w+/s*/}", "?"); mapper.setSql(sql); mapper.setParameterNames(paramNames); mapper.setSql(sql); if (resultType == List.class) { mapper.setSelectList(true); Type genericReturnType = method.getGenericReturnType(); ParameterizedType parameterizedType = (ParameterizedType) genericReturnType; Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; mapper.setResultType(actualTypeArgument.getTypeName()); mapper.setType("SELECT"); } else if (resultType == Integer.class || resultType == int.class) { mapper.setType("UPDATE"); } else { mapper.setType("SELECT"); mapper.setResultType(resultType.getName()); } return mapper; } }
首先拿到方法上的注解,得到用户填入的sql语句
如何深度理解mybatis?

文章插图
 
然后处理sql语句#{参数}的这些数据, 然后将参数的顺序保存起来, 用来后期设置参数的数据做准备, 一个


推荐阅读